diff options
author | Luke Kanies <luke@madstop.com> | 2007-09-21 13:07:34 -0500 |
---|---|---|
committer | Luke Kanies <luke@madstop.com> | 2007-09-21 13:07:34 -0500 |
commit | 7740cd497f936859fa5213c34dae485b5b70ba60 (patch) | |
tree | 9deae991695493bdfdadbab5bd39367bed6c5144 | |
parent | 4e8b6712b688b23d6cb33f5829d3b15fe9d6833c (diff) | |
download | puppet-7740cd497f936859fa5213c34dae485b5b70ba60.tar.gz puppet-7740cd497f936859fa5213c34dae485b5b70ba60.tar.xz puppet-7740cd497f936859fa5213c34dae485b5b70ba60.zip |
The indirector specs now all pass. I think I need
to add a few more specs, though.
-rw-r--r-- | lib/puppet/indirector.rb | 95 | ||||
-rw-r--r-- | lib/puppet/node.rb | 2 | ||||
-rwxr-xr-x | lib/puppet/node/facts.rb | 2 | ||||
-rwxr-xr-x | spec/unit/indirector/indirector.rb | 97 |
4 files changed, 63 insertions, 133 deletions
diff --git a/lib/puppet/indirector.rb b/lib/puppet/indirector.rb index cdfd28908..90f4d3d33 100644 --- a/lib/puppet/indirector.rb +++ b/lib/puppet/indirector.rb @@ -22,6 +22,7 @@ module Puppet::Indirector def name self.class.name end + def indirection self.class.indirection end @@ -77,82 +78,37 @@ module Puppet::Indirector def self.terminus(indirection, terminus) loaded_instance(indirection, terminus) end - - # clear out the list of known indirections -#JRB:TODO -- I would prefer to get rid of this altogether, but it's implicated in testing, given the class loader - def self.reset - @indirections = {} - @class_indirections = {} - end - - # return a hash of registered indirections, keys are indirection names, values are classes which handle the indirections - def self.indirections - @indirections ||= {} - @indirections - end - - # associate an indirection name with the class which handles the indirection - def self.register_indirection(name, klass) - @indirections ||= {} - @class_indirections ||= {} - - raise ArgumentError, "Already performing an indirection of %s; cannot redirect %s" % [name, klass.name] if @indirections[name] - raise ArgumentError, "Class %s is already redirecting to %s; cannot redirect to %s" % - [klass.name, @class_indirections[klass.name], name] if @class_indirections[klass.name] - @class_indirections[klass.name] = name - @indirections[name] = klass - end - - def self.terminus_for_indirection(name) -# JRB:TODO make this do something useful, aka look something up in a .yml file - # JRB:TODO look up name + '_source' in standard configuration - case name - when :node: :none - when :facts: :yaml - else - raise ArgumentError, "Unknown indirection" - end - end # Declare that the including class indirects its methods to # this terminus. The terminus name must be the name of a Puppet # default, not the value -- if it's the value, then it gets # evaluated at parse time, which is before the user has had a chance # to override it. - def indirects(indirection, options = {}) -#JRB:TODO remove options hash ^^^ - - # associate the name :node, with this class, Node - # also, do error checking (already registered, etc.) - Puppet::Indirector.register_indirection(indirection, self) - - # populate this registered class with the various new methods + def indirects(indirection) + raise(ArgumentError, "Already handling indirection for %s; cannot also handle %s" % [@indirection.name, indirection]) if defined?(@indirection) and indirection + # populate this class with the various new methods extend ClassMethods include InstanceMethods - # look up the type of Terminus for this name (:node => :ldap) - terminus = Puppet::Indirector.terminus_for_indirection(indirection) - # instantiate the actual Terminus for that type and this name (:ldap, w/ args :node) - # & hook the instantiated Terminus into this registered class (Node: @indirection = terminus) + # & hook the instantiated Terminus into this class (Node: @indirection = terminus) Puppet::Indirector.enable_autoloading_indirection indirection - raise("No Terminus %s for %s" % [terminus, indirection]) unless @indirection = Puppet::Indirector.terminus(indirection, terminus).new + @indirection = Puppet::Indirector::Indirection.new(indirection) end module ClassMethods attr_reader :indirection def find(*args) - self.indirection.find(*args) - # JRB:TODO look up the indirection, and call its .find method + indirection.find(*args) end def destroy(*args) - self.indirection.destroy(*args) + indirection.destroy(*args) end def search(*args) - self.indirection.search(*args) + indirection.search(*args) end end @@ -162,37 +118,4 @@ module Puppet::Indirector self.class.indirection.save(self, *args) end end - - # JRB:FIXME: these methods to be deprecated: - - # Define methods for each of the HTTP methods. These just point to the - # termini, with consistent error-handling. Each method is called with - # the first argument being the indirection type and the rest of the - # arguments passed directly on to the indirection terminus. There is - # currently no attempt to standardize around what the rest of the arguments - # should allow or include or whatever. - # There is also no attempt to pre-validate that a given indirection supports - # the method in question. We should probably require that indirections - # declare supported methods, and then verify that termini implement all of - # those methods. - # [:get, :post, :put, :delete].each do |method_name| - # define_method(method_name) do |*args| - # redirect(method_name, *args) - # end - # end - # - # private - # - # - # # JRB:TODO this needs to be renamed, as it actually ends up on the model class, where it might conflict with something - # # Redirect one of our methods to the corresponding method on the Terminus - # def redirect(method_name, *args) - # begin - # @indirection.terminus.send(method_name, *args) - # rescue NoMethodError => detail - # puts detail.backtrace if Puppet[:trace] - # raise ArgumentError, "The %s terminus of the %s indirection failed to respond to %s: %s" % - # [@indirection.terminus.name, @indirection.name, method_name, detail] - # end - # end end diff --git a/lib/puppet/node.rb b/lib/puppet/node.rb index 852f98a99..f8ede1858 100644 --- a/lib/puppet/node.rb +++ b/lib/puppet/node.rb @@ -9,7 +9,7 @@ class Puppet::Node extend Puppet::Indirector # Use the node source as the indirection terminus. - indirects :node, :to => :node_source + indirects :node # Add the node-searching methods. This is what people will actually # interact with that will find the node with the list of names or diff --git a/lib/puppet/node/facts.rb b/lib/puppet/node/facts.rb index e5774127b..a2e6d9c04 100755 --- a/lib/puppet/node/facts.rb +++ b/lib/puppet/node/facts.rb @@ -9,7 +9,7 @@ class Puppet::Node::Facts extend Puppet::Indirector # Use the node source as the indirection terminus. - indirects :facts, :to => :fact_store + indirects :facts attr_accessor :name, :values diff --git a/spec/unit/indirector/indirector.rb b/spec/unit/indirector/indirector.rb index 1a9704e5e..2e22090b0 100755 --- a/spec/unit/indirector/indirector.rb +++ b/spec/unit/indirector/indirector.rb @@ -3,73 +3,80 @@ require 'puppet/defaults' require 'puppet/indirector' describe Puppet::Indirector, " when available to a model" do + before do + @thingie = Class.new do + extend Puppet::Indirector + end + end + + it "should provide a way for the model to register an indirection under a name" do + @thingie.should respond_to(:indirects) + end +end + +describe Puppet::Indirector, "when registering an indirection" do + before do + @thingie = Class.new do + extend Puppet::Indirector + end + end + + it "should require a name when registering a model" do + Proc.new {@thingie.send(:indirects) }.should raise_error(ArgumentError) + end + + it "should create an indirection instance to manage each indirecting model" do + @indirection = @thingie.indirects(:test) + @indirection.should be_instance_of(Puppet::Indirector::Indirection) + end + + it "should not allow a model to register under multiple names" do + # Keep track of the indirection instance so we can delete it on cleanup + @indirection = @thingie.indirects :first + Proc.new { @thingie.indirects :second }.should raise_error(ArgumentError) + end + + after do + @indirection.delete if @indirection + end + +# TODO: node lookup retries/searching +end + +describe Puppet::Indirector, " when redirecting model" do before do @thingie = Class.new do extend Puppet::Indirector end - end - - it "should provide a way for the model to register an indirection under a name" do - @thingie.should respond_to(:indirects) + @mock_terminus = mock('Terminus') + @indirection = @thingie.send(:indirects, :test) + @thingie.expects(:indirection).returns(@mock_terminus) end it "should give model the ability to lookup a model instance by letting the indirection perform the lookup" do - @thingie.send(:indirects, :node) - mock_terminus = mock('Terminus') - mock_terminus.expects(:find) - @thingie.expects(:indirection).returns(mock_terminus) + @mock_terminus.expects(:find) @thingie.find end it "should give model the ability to remove model instances from a terminus by letting the indirection remove the instance" do - @thingie.send(:indirects, :node) - mock_terminus = mock('Terminus') - mock_terminus.expects(:destroy) - @thingie.expects(:indirection).returns(mock_terminus) + @mock_terminus.expects(:destroy) @thingie.destroy end it "should give model the ability to search for model instances by letting the indirection find the matching instances" do - @thingie.send(:indirects, :node) - mock_terminus = mock('Terminus') - mock_terminus.expects(:search) - @thingie.expects(:indirection).returns(mock_terminus) + @mock_terminus.expects(:search) @thingie.search end it "should give model the ability to store a model instance by letting the indirection store the instance" do - @thingie.send(:indirects, :node) - mock_terminus = mock('Terminus') - mock_terminus.expects(:save) - @thingie.expects(:indirection).returns(mock_terminus) - @thingie.new.save - end -end - -describe Puppet::Indirector, "when registering an indirection" do - before do - Puppet::Indirector.reset - @thingie = Class.new do - extend Puppet::Indirector - end - Puppet::Indirector.stubs(:terminus_for_indirection).returns(:ldap) - @terminus = mock 'terminus' - @terminus_class = stub 'terminus class', :new => @terminus - Puppet::Indirector.stubs(:terminus).returns(@terminus_class) + thing = @thingie.new + @mock_terminus.expects(:save).with(thing) + thing.save end - it "should require a name when registering a model" do - Proc.new {@thingie.send(:indirects) }.should raise_error(ArgumentError) + after do + @indirection.delete end - - it "should not allow a model to register under multiple names" do - @thingie.send(:indirects, :first) - Proc.new {@thingie.send(:indirects, :second)}.should raise_error(ArgumentError) - end - - it "should create an indirection instance to manage each indirecting model" - -# TODO: node lookup retries/searching end |