diff options
| author | Luke Kanies <luke@madstop.com> | 2007-09-25 15:52:26 -0500 |
|---|---|---|
| committer | Luke Kanies <luke@madstop.com> | 2007-09-25 15:52:26 -0500 |
| commit | 938b91894d09ea804d2fc9eaac57b52f46de793a (patch) | |
| tree | 932455f303de4f4ed3435b301ea949e7f1e9babb | |
| parent | 8ec60118684fc32b65ce70ccfc009e07b7e6a3cd (diff) | |
| download | puppet-938b91894d09ea804d2fc9eaac57b52f46de793a.tar.gz puppet-938b91894d09ea804d2fc9eaac57b52f46de793a.tar.xz puppet-938b91894d09ea804d2fc9eaac57b52f46de793a.zip | |
Adding cache support to indirection. If you have
a '<indirection>_cache' setting, then the indirection
will use the value there as the name of the cache.
| -rw-r--r-- | lib/puppet/indirector/indirection.rb | 32 | ||||
| -rwxr-xr-x | spec/unit/indirector/indirection.rb | 145 |
2 files changed, 153 insertions, 24 deletions
diff --git a/lib/puppet/indirector/indirection.rb b/lib/puppet/indirector/indirection.rb index 8afe0012d..9cc116e40 100644 --- a/lib/puppet/indirector/indirection.rb +++ b/lib/puppet/indirector/indirection.rb @@ -15,9 +15,36 @@ class Puppet::Indirector::Indirection attr_accessor :name, :model - # Clear our cached list of termini. + # Create and return our cache terminus. + def cache + terminus(cache_name) + end + + # Should we use a cache? + def cache? + cache_name ? true : false + end + + # Figure out the cache name, if there is one. If there's no name, then + # caching is disabled. + def cache_name + unless @cache_name + setting_name = "%s_cache" % self.name + if ! Puppet.settings.valid?(setting_name) or (value = Puppet.settings[setting_name] and value == "none") + @cache_name = nil + else + @cache_name = value + @cache_name = @cache_name.intern if @cache_name.is_a?(String) + end + end + @cache_name + end + + # Clear our cached list of termini, and reset the cache name + # so it's looked up again. # This is only used for testing. def clear_cache + @cache_name = nil @termini.clear end @@ -38,6 +65,7 @@ class Puppet::Indirector::Indirection end @termini = {} @terminus_types = {} + @cache_name = nil raise(ArgumentError, "Indirection %s is already defined" % @name) if @@indirections.find { |i| i.name == @name } @@indirections << self end @@ -66,6 +94,7 @@ class Puppet::Indirector::Indirection end def destroy(*args) + cache.destroy(*args) if cache? terminus.destroy(*args) end @@ -75,6 +104,7 @@ class Puppet::Indirector::Indirection # these become instance methods def save(*args) + cache.save(*args) if cache? terminus.save(*args) end diff --git a/spec/unit/indirector/indirection.rb b/spec/unit/indirector/indirection.rb index 326b6b470..41f50522f 100755 --- a/spec/unit/indirector/indirection.rb +++ b/spec/unit/indirector/indirection.rb @@ -4,6 +4,39 @@ require File.dirname(__FILE__) + '/../../spec_helper' require 'puppet/indirector' +describe Puppet::Indirector::Indirection do + before do + @indirection = Puppet::Indirector::Indirection.new(mock('model'), :test) + @terminus = mock 'terminus' + @indirection.stubs(:terminus).returns(@terminus) + end + + it "should handle lookups of a model instance by letting the appropriate terminus perform the lookup" do + @terminus.expects(:find).with(:mything).returns(:whev) + @indirection.find(:mything).should == :whev + end + + it "should handle removing model instances from a terminus letting the appropriate terminus remove the instance" do + @terminus.expects(:destroy).with(:mything).returns(:whev) + @indirection.destroy(:mything).should == :whev + end + + it "should handle searching for model instances by letting the appropriate terminus find the matching instances" do + @terminus.expects(:search).with(:mything).returns(:whev) + @indirection.search(:mything).should == :whev + end + + it "should handle storing a model instance by letting the appropriate terminus store the instance" do + @terminus.expects(:save).with(:mything).returns(:whev) + @indirection.save(:mything).should == :whev + end + + after do + @indirection.delete + Puppet::Indirector::Indirection.clear_cache + end +end + describe Puppet::Indirector::Indirection, " when initializing" do it "should keep a reference to the indirecting model" do model = mock 'model' @@ -126,32 +159,98 @@ describe Puppet::Indirector::Indirection, " when managing terminus instances" do end end -describe Puppet::Indirector::Indirection do - before do +describe Puppet::Indirector::Indirection, " when deciding whether to cache" do + before do @indirection = Puppet::Indirector::Indirection.new(mock('model'), :test) @terminus = mock 'terminus' @indirection.stubs(:terminus).returns(@terminus) - end - - it "should handle lookups of a model instance by letting the appropriate terminus perform the lookup" do - @terminus.expects(:find).with(:mything).returns(:whev) - @indirection.find(:mything).should == :whev - end - - it "should handle removing model instances from a terminus letting the appropriate terminus remove the instance" do - @terminus.expects(:destroy).with(:mything).returns(:whev) - @indirection.destroy(:mything).should == :whev - end - - it "should handle searching for model instances by letting the appropriate terminus find the matching instances" do - @terminus.expects(:search).with(:mything).returns(:whev) - @indirection.search(:mything).should == :whev - end - - it "should handle storing a model instance by letting the appropriate terminus store the instance" do - @terminus.expects(:save).with(:mything).returns(:whev) - @indirection.save(:mything).should == :whev - end + end + + it "should not use a cache if there no cache setting" do + Puppet.settings.expects(:valid?).with("test_cache").returns(false) + @indirection.expects(:cache).never + @terminus.stubs(:save) + @indirection.save(:whev) + end + + it "should not use a cache if the cache setting is set to 'none'" do + Puppet.settings.expects(:valid?).with("test_cache").returns(true) + Puppet.settings.expects(:value).with("test_cache").returns("none") + @indirection.expects(:cache).never + @terminus.stubs(:save) + @indirection.save(:whev) + end + + it "should use a cache if there is a related cache setting and it is not set to 'none'" do + Puppet.settings.expects(:valid?).with("test_cache").returns(true) + Puppet.settings.expects(:value).with("test_cache").returns("something") + cache = mock 'cache' + cache.expects(:save).with(:whev) + @indirection.expects(:cache).returns(cache) + @terminus.stubs(:save) + @indirection.save(:whev) + end + + after do + @indirection.delete + Puppet::Indirector::Indirection.clear_cache + end +end + +describe Puppet::Indirector::Indirection, " when using a cache" do + before do + Puppet.settings.stubs(:valid?).returns(true) + Puppet.settings.stubs(:value).with("test_terminus").returns("test_terminus") + @terminus_class = mock 'terminus_class' + @terminus = mock 'terminus' + @terminus_class.stubs(:new).returns(@terminus) + @cache = mock 'cache' + @cache_class = mock 'cache_class' + Puppet::Indirector::Terminus.stubs(:terminus_class).with(:cache_terminus, :test).returns(@cache_class) + Puppet::Indirector::Terminus.stubs(:terminus_class).with(:test_terminus, :test).returns(@terminus_class) + @indirection = Puppet::Indirector::Indirection.new(mock('model'), :test) + end + + it "should copy all writing indirection calls to the cache terminus" do + @cache_class.expects(:new).returns(@cache) + Puppet.settings.stubs(:value).with("test_cache").returns("cache_terminus") + @cache.expects(:save).with(:whev) + @terminus.stubs(:save) + @indirection.save(:whev) + end + + it "should not create a cache terminus at initialization" do + # This is weird, because all of the code is in the setup. If we got + # new() called on the cache class, we'd get an exception here. + end + + it "should reuse the cache terminus" do + @cache_class.expects(:new).returns(@cache) + Puppet.settings.stubs(:value).with("test_cache").returns("cache_terminus") + @indirection.cache.should equal(@cache) + @indirection.cache.should equal(@cache) + end + + it "should remove the cache terminus when all other terminus instances are cleared" do + cache2 = mock 'cache2' + @cache_class.stubs(:new).returns(@cache, cache2) + Puppet.settings.stubs(:value).with("test_cache").returns("cache_terminus") + @indirection.cache.should equal(@cache) + @indirection.clear_cache + @indirection.cache.should equal(cache2) + end + + it "should look up the cache name when recreating the cache terminus after terminus instances have been cleared" do + cache_class2 = mock 'cache_class2' + cache2 = mock 'cache2' + cache_class2.expects(:new).returns(cache2) + @cache_class.expects(:new).returns(@cache) + Puppet::Indirector::Terminus.stubs(:terminus_class).with(:other_cache, :test).returns(cache_class2) + Puppet.settings.stubs(:value).with("test_cache").returns("cache_terminus", "other_cache") + @indirection.cache.should equal(@cache) + @indirection.clear_cache + @indirection.cache.should equal(cache2) + end after do @indirection.delete |
