summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG5
-rw-r--r--lib/facter/kernelrelease.rb2
-rw-r--r--lib/facter/util/collection.rb28
-rw-r--r--lib/facter/util/fact.rb14
-rw-r--r--lib/facter/util/resolution.rb21
-rwxr-xr-xspec/unit/util/collection.rb40
-rwxr-xr-xspec/unit/util/fact.rb7
-rwxr-xr-xspec/unit/util/resolution.rb16
8 files changed, 107 insertions, 26 deletions
diff --git a/CHANGELOG b/CHANGELOG
index b4d5770..070bee6 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,4 +1,9 @@
?:
+ Set the timeout on the AIX kernelrelease fact to 5 seconds.
+
+ Refactored so each fact resolution can specify a separate timeout,
+ but the default is still 0.5.
+
Refactered ipmess.rb and util/ip.rb to support separate *BSD logic for
*BSD aliased interfaces.
diff --git a/lib/facter/kernelrelease.rb b/lib/facter/kernelrelease.rb
index 8c6ac57..652fd6a 100644
--- a/lib/facter/kernelrelease.rb
+++ b/lib/facter/kernelrelease.rb
@@ -2,7 +2,7 @@
setcode 'uname -r'
end
- Facter.add(:kernelrelease) do
+ Facter.add(:kernelrelease, :timeout => 5) do
confine :kernel => :aix
setcode 'oslevel -s'
end
diff --git a/lib/facter/util/collection.rb b/lib/facter/util/collection.rb
index edc65c7..3f8e0f8 100644
--- a/lib/facter/util/collection.rb
+++ b/lib/facter/util/collection.rb
@@ -17,11 +17,35 @@ class Facter::Util::Collection
name = canonize(name)
unless fact = @facts[name]
- fact = Facter::Util::Fact.new(name, options)
+ fact = Facter::Util::Fact.new(name)
+
@facts[name] = fact
end
- fact.add(&block) if block
+ # Set any fact-appropriate options.
+ options.each do |opt, value|
+ method = opt.to_s + "="
+ if fact.respond_to?(method)
+ fact.send(method, value)
+ options.delete(opt)
+ end
+ end
+
+ if block
+ resolve = fact.add(&block)
+ # Set any resolve-appropriate options
+ options.each do |opt, value|
+ method = opt.to_s + "="
+ if resolve.respond_to?(method)
+ resolve.send(method, value)
+ options.delete(opt)
+ end
+ end
+ end
+
+ unless options.empty?
+ raise ArgumentError, "Invalid facter option(s) %s" % options.keys.collect { |k| k.to_s }.join(",")
+ end
return fact
end
diff --git a/lib/facter/util/fact.rb b/lib/facter/util/fact.rb
index 0b2d5b9..c96ca3b 100644
--- a/lib/facter/util/fact.rb
+++ b/lib/facter/util/fact.rb
@@ -1,9 +1,9 @@
require 'facter'
require 'facter/util/resolution'
-require 'timeout'
-
class Facter::Util::Fact
+ TIMEOUT = 5
+
attr_accessor :name, :searching, :ldapname
# Create a new fact, with no resolution mechanisms.
@@ -82,15 +82,7 @@ class Facter::Util::Fact
next unless resolve.suitable?
foundsuits = true
- tmp = nil
- begin
- Timeout.timeout(0.5) do
- tmp = resolve.value
- end
- rescue Timeout::Error => detail
- warn "Timed out seeking value for %s" % self.name
- next
- end
+ tmp = resolve.value
break tmp unless tmp.nil? or tmp == ""
}
diff --git a/lib/facter/util/resolution.rb b/lib/facter/util/resolution.rb
index b6aae77..1feda3f 100644
--- a/lib/facter/util/resolution.rb
+++ b/lib/facter/util/resolution.rb
@@ -5,8 +5,10 @@
# suitable.
require 'facter/util/confine'
+require 'timeout'
+
class Facter::Util::Resolution
- attr_accessor :interpreter, :code, :name
+ attr_accessor :interpreter, :code, :name, :timeout
def self.have_which
if @have_which.nil?
@@ -60,6 +62,7 @@ class Facter::Util::Resolution
@name = name
@confines = []
@value = nil
+ @timeout = 0.5
end
# Return the number of confines.
@@ -95,10 +98,18 @@ class Facter::Util::Resolution
# How we get a value for our resolution mechanism.
def value
- if @code.is_a?(Proc)
- result = @code.call()
- else
- result = Facter::Util::Resolution.exec(@code,@interpreter)
+ result = nil
+ begin
+ Timeout.timeout(timeout) do
+ if @code.is_a?(Proc)
+ result = @code.call()
+ else
+ result = Facter::Util::Resolution.exec(@code,@interpreter)
+ end
+ end
+ rescue Timeout::Error => detail
+ warn "Timed out seeking value for %s" % self.name
+ return nil
end
return nil if result == ""
diff --git a/spec/unit/util/collection.rb b/spec/unit/util/collection.rb
index 81e5d98..7585a52 100755
--- a/spec/unit/util/collection.rb
+++ b/spec/unit/util/collection.rb
@@ -44,6 +44,46 @@ describe Facter::Util::Collection do
@coll.add(:myname)
end
+ it "should accept options" do
+ @coll.add(:myname, :ldapname => "whatever") { }
+ end
+
+ it "should set any appropriate options on the fact instances" do
+ # Use a real fact instance, because we're using respond_to?
+ fact = Facter::Util::Fact.new(:myname)
+ fact.expects(:ldapname=).with("testing")
+ Facter::Util::Fact.expects(:new).with(:myname).returns fact
+
+ @coll.add(:myname, :ldapname => "testing")
+ end
+
+ it "should set appropriate options on the resolution instance" do
+ fact = Facter::Util::Fact.new(:myname)
+ Facter::Util::Fact.expects(:new).with(:myname).returns fact
+
+ resolve = Facter::Util::Resolution.new(:myname) {}
+ fact.expects(:add).returns resolve
+
+ @coll.add(:myname, :timeout => "myval") {}
+ end
+
+ it "should not pass fact-specific options to resolutions" do
+ fact = Facter::Util::Fact.new(:myname)
+ Facter::Util::Fact.expects(:new).with(:myname).returns fact
+
+ resolve = Facter::Util::Resolution.new(:myname) {}
+ fact.expects(:add).returns resolve
+
+ fact.expects(:ldapname=).with("foo")
+ resolve.expects(:timeout=).with("myval")
+
+ @coll.add(:myname, :timeout => "myval", :ldapname => "foo") {}
+ end
+
+ it "should fail if invalid options are provided" do
+ lambda { @coll.add(:myname, :foo => :bar) }.should raise_error(ArgumentError)
+ end
+
describe "and a block is provided" do
it "should use the block to add a resolution to the fact" do
fact = mock 'fact'
diff --git a/spec/unit/util/fact.rb b/spec/unit/util/fact.rb
index cee70b9..1652032 100755
--- a/spec/unit/util/fact.rb
+++ b/spec/unit/util/fact.rb
@@ -121,13 +121,6 @@ describe Facter::Util::Fact do
@fact.value.should be_nil
end
-
- it "should timeout after 0.5 seconds" do
- @fact.expects(:warn)
- @fact.add { setcode { sleep 2; raise "This is a test" } }
-
- @fact.value.should be_nil
- end
end
it "should have a method for flushing the cached fact" do
diff --git a/spec/unit/util/resolution.rb b/spec/unit/util/resolution.rb
index 493ee3a..e546713 100755
--- a/spec/unit/util/resolution.rb
+++ b/spec/unit/util/resolution.rb
@@ -17,6 +17,14 @@ describe Facter::Util::Resolution 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.5 seconds" do
+ Facter::Util::Resolution.new("yay").timeout.should == 0.5
+ end
+
describe "when setting the code" do
before do
@resolve = Facter::Util::Resolution.new("yay")
@@ -82,6 +90,14 @@ describe Facter::Util::Resolution do
@resolve.setcode { "" }
@resolve.value.should be_nil
end
+
+ it "should timeout after the provided timeout" do
+ @resolve.expects(:warn)
+ @resolve.timeout = 0.1
+ @resolve.setcode { sleep 2; raise "This is a test" }
+
+ @resolve.value.should be_nil
+ end
end
end