[Pkg-puppet-devel] [facter] 154/180: (maint) Avoid repeated fact evaluation against different loaders

Stig Sandbeck Mathisen ssm at debian.org
Mon Jun 30 15:06: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 ded4090cbe3a4cbc8a11660ec13c561c37f06f42
Author: Josh Cooper <josh at puppetlabs.com>
Date:   Thu Jun 19 16:49:41 2014 -0700

    (maint) Avoid repeated fact evaluation against different loaders
    
    Commit 4d937456e fixed an infinite recursion problem where Facter could load
    a fact, e.g. ec2, and outside of the setcode body, the fact could reference
    another fact, e.g. macaddress, that had not yet been evaluated. This results
    in a fact cache miss, causing Facter to reload all facts, including the
    original one, e.g. ec2, leading to an infinite loop.
    
    The spec test was written to load nosuchfact.rb, which contained ruby
    code that tried to resolve :nosuchfact, causing a cache miss, and
    to ensure we didn't infinitely recurse.
    
    However, the spec test did not account that there are two loaders in play,
    so if you run:
    
        $ bundle exec rspec spec/unit/util/loader_spec.rb
        Already evaluated rest at /Users/josh/work/facter/lib/facter/ec2.rb:4, reevaluating anyways
        Already evaluated rest at /Users/josh/work/facter/lib/facter/ec2.rb:21, reevaluating anyways
    
    The reason is because the spec test creates a loader that defines the
    ec2 fact and its rest resolution. However, when nosuchfact.rb is loaded,
    it calls Facter.value, which delegates to a different loader than the one the
    test created. As a result, the ec2 fact is evaluated twice.
    
    This commit simplifies the spec test to ensure that Kernel.load is only
    called once for a given fact.
---
 lib/facter/util/loader.rb                    | 11 ++++++++++-
 spec/fixtures/unit/util/loader/nosuchfact.rb |  1 -
 spec/unit/util/loader_spec.rb                |  8 ++++----
 3 files changed, 14 insertions(+), 6 deletions(-)

diff --git a/lib/facter/util/loader.rb b/lib/facter/util/loader.rb
index 0f31bd5..37dd177 100644
--- a/lib/facter/util/loader.rb
+++ b/lib/facter/util/loader.rb
@@ -112,7 +112,7 @@ class Facter::Util::Loader
     begin
       # Store the file path so we don't try to reload it
       @loaded << file
-      Kernel.load(file)
+      kernel_load(file)
     rescue ScriptError => detail
       # Don't store the path if the file can't be loaded
       # in case it's loadable later on.
@@ -121,6 +121,15 @@ class Facter::Util::Loader
     end
   end
 
+  # Load and execute the Ruby program specified in the file. This exists
+  # for testing purposes.
+  #
+  # @api private
+  # @return [Boolean]
+  def kernel_load(file)
+    Kernel.load(file)
+  end
+
   # Load facts from the environment.  If no name is provided,
   # all will be loaded.
   def load_env(fact = nil)
diff --git a/spec/fixtures/unit/util/loader/nosuchfact.rb b/spec/fixtures/unit/util/loader/nosuchfact.rb
deleted file mode 100644
index f0ba60a..0000000
--- a/spec/fixtures/unit/util/loader/nosuchfact.rb
+++ /dev/null
@@ -1 +0,0 @@
-Facter.value(:nosuchfact)
diff --git a/spec/unit/util/loader_spec.rb b/spec/unit/util/loader_spec.rb
index 667d96c..b87a196 100755
--- a/spec/unit/util/loader_spec.rb
+++ b/spec/unit/util/loader_spec.rb
@@ -277,10 +277,10 @@ describe Facter::Util::Loader do
   end
 
   it "should load facts on the facter search path only once" do
-    facterlibdir = File.expand_path(File.dirname(__FILE__) + '../../../fixtures/unit/util/loader')
+    loader = loader_from(:env => {})
+    loader.load_all
 
-    Facter::Util::Loader.new('FACTERLIB' => facterlibdir).load_all
-
-    Facter.value(:nosuchfact).should be_nil
+    loader.expects(:kernel_load).with(regexp_matches(/ec2/)).never
+    loader.load(:ec2)
   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