From 02275f0b29cee70e3f02d6d8f911eaaf3fad579d Mon Sep 17 00:00:00 2001 From: Luke Kanies Date: Fri, 21 Sep 2007 15:49:25 -0500 Subject: Adding automatic association between terminus subclasses and the indirection they're working with. It looks like I'll be moving terminus registration to the indirection rather than the top-level Indirector. --- lib/puppet/indirector/facts/yaml.rb | 41 ------------------------ lib/puppet/indirector/terminus.rb | 23 ++++++++++++++ lib/puppet/indirector/yaml/facts.rb | 7 +++++ spec/unit/indirector/terminus.rb | 62 ++++++++++++++++++++++++++++++++++--- 4 files changed, 88 insertions(+), 45 deletions(-) delete mode 100644 lib/puppet/indirector/facts/yaml.rb create mode 100644 lib/puppet/indirector/yaml/facts.rb diff --git a/lib/puppet/indirector/facts/yaml.rb b/lib/puppet/indirector/facts/yaml.rb deleted file mode 100644 index cb02f05c6..000000000 --- a/lib/puppet/indirector/facts/yaml.rb +++ /dev/null @@ -1,41 +0,0 @@ -Puppet::Indirector.register_terminus :facts, :yaml do - desc "Store client facts as flat files, serialized using YAML." - - # Get a client's facts. - def find(node) - file = path(node) - - return nil unless FileTest.exists?(file) - - begin - values = YAML::load(File.read(file)) - rescue => detail - Puppet.err "Could not load facts for %s: %s" % [node, detail] - end - - Puppet::Node::Facts.new(node, values) - end - - def initialize - Puppet.config.use(:yamlfacts) - end - - # Store the facts to disk. - def save(facts) - File.open(path(facts.name), "w", 0600) do |f| - begin - f.print YAML::dump(facts.values) - rescue => detail - Puppet.err "Could not write facts for %s: %s" % [facts.name, detail] - end - end - nil - end - - private - - # Return the path to a given node's file. - def path(name) - File.join(Puppet[:yamlfactdir], name + ".yaml") - end -end diff --git a/lib/puppet/indirector/terminus.rb b/lib/puppet/indirector/terminus.rb index 4d550e9ba..a98f6dff0 100644 --- a/lib/puppet/indirector/terminus.rb +++ b/lib/puppet/indirector/terminus.rb @@ -20,6 +20,29 @@ class Puppet::Indirector::Terminus raise ArgumentError, "Could not find indirection instance %s" % name end end + + # Register our subclass with the appropriate indirection. + # This follows the convention that our terminus is named after the + # indirection. + def inherited(subclass) + longname = subclass.to_s + if longname =~ /# :mystuff + Puppet::Indirector::Indirection.stubs(:instance).with(:mystuff).returns(@indirection) + @terminus = Class.new(Puppet::Indirector::Terminus) do + def self.to_s + "Terminus::Type::MyStuff" + end + end end it "should support the documentation methods" do @@ -39,16 +45,64 @@ describe Puppet::Indirector::Terminus do it "should fail when provided a name that does not resolve to an indirection" do Puppet::Indirector::Indirection.expects(:instance).with(:myind).returns(nil) proc { @terminus.indirection = :myind }.should raise_error(ArgumentError) - @terminus.indirection.should be_nil + + # It shouldn't overwrite our existing one (or, more normally, it shouldn't set + # anything). + @terminus.indirection.should equal(@indirection) + end +end + +describe Puppet::Indirector::Terminus, " when being subclassed" do + it "should associate the subclass with an indirection based on the subclass constant" do + indirection = mock 'indirection' + Puppet::Indirector::Indirection.expects(:instance).with(:myindirection).returns(indirection) + + klass = Class.new(Puppet::Indirector::Terminus) do + def self.to_s + "Puppet::Indirector::Terminus::MyIndirection" + end + end + + klass.indirection.should equal(indirection) + end + + it "should fail when the terminus subclass does not include its parent class in the constant path" do + indirection = mock 'indirection' + Puppet::Indirector::Indirection.expects(:instance).with(:myindirection).returns(indirection) + + proc { + klass = Class.new(Puppet::Indirector::Terminus) do + def self.to_s + "MyIndirection" + end + end + }.should raise_error(ArgumentError) + end + + it "should set the subclass's name to the terminus type" do + indirection = mock 'indirection' + Puppet::Indirector::Indirection.expects(:instance).with(:myindirection).returns(indirection) + + klass = Class.new(Puppet::Indirector::Terminus) do + def self.to_s + "Puppet::Indirector::Terminus::Yaml::MyIndirection" + end + end + + klass.name.should == :yaml end end describe Puppet::Indirector::Terminus, " when a terminus instance" do before do @indirection = stub 'indirection', :name => :myyaml - @terminus_class = Class.new(Puppet::Indirector::Terminus) + Puppet::Indirector::Indirection.stubs(:instance).with(:mystuff).returns(@indirection) + @terminus_class = Class.new(Puppet::Indirector::Terminus) do + def self.to_s + "Terminus::Type::MyStuff" + end + end @terminus_class.name = :test - @terminus_class.stubs(:indirection).returns(@indirection) @terminus = @terminus_class.new end -- cgit