summaryrefslogtreecommitdiffstats
path: root/spec/unit
diff options
context:
space:
mode:
authorLuke Kanies <luke@madstop.com>2007-09-22 00:16:39 -0500
committerLuke Kanies <luke@madstop.com>2007-09-22 00:16:39 -0500
commitebe7290bf0c9119e268c9037c33da515e527aa5b (patch)
tree3f59b5b3fc46c35f5ef18e0a1110381c94187692 /spec/unit
parentb9dc6cb22f087f419b328cafa945c9604043b22f (diff)
downloadpuppet-ebe7290bf0c9119e268c9037c33da515e527aa5b.tar.gz
puppet-ebe7290bf0c9119e268c9037c33da515e527aa5b.tar.xz
puppet-ebe7290bf0c9119e268c9037c33da515e527aa5b.zip
All indirections are working, and they have all
been migrated over to the new organization. Where we would have previously had an 'ldap' node terminus at puppet/indirector/node/ldap.rb, we would not have it at puppet/indirector/ldap/node.rb, and it would be a subclass of puppet/indirector/ldap.rb. These are called terminus classes, and there are now three categories of them: The base class itself, abstract classes that provide most of the functionality (e.g., the ldap and yaml classes), and the classes themselves that implement the functionality for a given model like Node or Facts. The base terminus class handles auto-loading any of these classes from disk.
Diffstat (limited to 'spec/unit')
-rwxr-xr-xspec/unit/indirector/exec.rb49
-rwxr-xr-xspec/unit/indirector/exec/node.rb62
-rwxr-xr-xspec/unit/indirector/indirection.rb20
-rwxr-xr-xspec/unit/indirector/ldap.rb147
-rwxr-xr-xspec/unit/indirector/ldap/node.rb84
-rwxr-xr-xspec/unit/indirector/node/external.rb119
-rwxr-xr-xspec/unit/indirector/node/ldap.rb243
-rwxr-xr-xspec/unit/indirector/node/none.rb32
-rwxr-xr-xspec/unit/indirector/null.rb27
-rwxr-xr-xspec/unit/indirector/null/node.rb18
-rwxr-xr-xspec/unit/indirector/terminus.rb14
11 files changed, 414 insertions, 401 deletions
diff --git a/spec/unit/indirector/exec.rb b/spec/unit/indirector/exec.rb
new file mode 100755
index 000000000..42fbe0955
--- /dev/null
+++ b/spec/unit/indirector/exec.rb
@@ -0,0 +1,49 @@
+#!/usr/bin/env ruby
+
+require File.dirname(__FILE__) + '/../../spec_helper'
+
+require 'puppet/indirector/exec'
+
+describe Puppet::Indirector::Exec do
+ before do
+ @indirection = mock 'indirection'
+ Puppet::Indirector::Indirection.expects(:instance).with(:testing).returns(@indirection)
+ @exec_class = Class.new(Puppet::Indirector::Exec) do
+ def self.to_s
+ "Testing"
+ end
+
+ attr_accessor :command
+ end
+
+ @searcher = @exec_class.new
+ @searcher.command = ["/echo"]
+ end
+
+ it "should throw an exception if the command is not an array" do
+ @searcher.command = "/usr/bin/echo"
+ proc { @searcher.find("foo") }.should raise_error(Puppet::DevError)
+ end
+
+ it "should throw an exception if the command is not fully qualified" do
+ @searcher.command = ["mycommand"]
+ proc { @searcher.find("foo") }.should raise_error(ArgumentError)
+ end
+
+ it "should execute the command with the object name as the only argument" do
+ @searcher.expects(:execute).with(%w{/echo yay})
+ @searcher.find("yay")
+ end
+
+ it "should return the output of the script" do
+ @searcher.expects(:execute).with(%w{/echo yay}).returns("whatever")
+ @searcher.find("yay").should == "whatever"
+ end
+
+ it "should return nil when the command produces no output" do
+ @searcher.expects(:execute).with(%w{/echo yay}).returns(nil)
+ @searcher.find("yay").should be_nil
+ end
+
+ it "should be able to execute commands with multiple arguments"
+end
diff --git a/spec/unit/indirector/exec/node.rb b/spec/unit/indirector/exec/node.rb
new file mode 100755
index 000000000..2eaf3c12e
--- /dev/null
+++ b/spec/unit/indirector/exec/node.rb
@@ -0,0 +1,62 @@
+#!/usr/bin/env ruby
+
+require File.dirname(__FILE__) + '/../../../spec_helper'
+
+require 'puppet/indirector/exec/node'
+
+describe Puppet::Indirector::Exec::Node, " when constructing the command to run" do
+ before do
+ @indirection = mock 'indirection'
+ Puppet.config.stubs(:value).with(:external_nodes).returns("/echo")
+ @searcher = Puppet::Indirector::Exec::Node.new
+ end
+
+ it "should use the external_node script as the command" do
+ Puppet.expects(:[]).with(:external_nodes).returns("/bin/echo")
+ @searcher.command.should == %w{/bin/echo}
+ end
+
+ it "should throw an exception if no external node command is set" do
+ Puppet.expects(:[]).with(:external_nodes).returns("none")
+ proc { @searcher.find("foo") }.should raise_error(ArgumentError)
+ end
+end
+
+describe Puppet::Indirector::Exec::Node, " when handling the results of the command" do
+ before do
+ @indirection = mock 'indirection'
+ Puppet.config.stubs(:value).with(:external_nodes).returns("/echo")
+ @searcher = Puppet::Indirector::Exec::Node.new
+ @node = stub 'node', :fact_merge => nil
+ @name = "yay"
+ Puppet::Node.expects(:new).with(@name).returns(@node)
+ @result = {}
+ # Use a local variable so the reference is usable in the execute() definition.
+ result = @result
+ @searcher.meta_def(:execute) do |command|
+ return YAML.dump(result)
+ end
+ end
+
+ it "should translate the YAML into a Node instance" do
+ # Use an empty hash
+ @searcher.find(@name).should equal(@node)
+ end
+
+ it "should set the resulting parameters as the node parameters" do
+ @result[:parameters] = {"a" => "b", "c" => "d"}
+ @node.expects(:parameters=).with "a" => "b", "c" => "d"
+ @searcher.find(@name)
+ end
+
+ it "should set the resulting classes as the node classes" do
+ @result[:classes] = %w{one two}
+ @node.expects(:classes=).with %w{one two}
+ @searcher.find(@name)
+ end
+
+ it "should merge the node's facts with its parameters" do
+ @node.expects(:fact_merge)
+ @searcher.find(@name)
+ end
+end
diff --git a/spec/unit/indirector/indirection.rb b/spec/unit/indirector/indirection.rb
index 5866f2d5f..e57f12072 100755
--- a/spec/unit/indirector/indirection.rb
+++ b/spec/unit/indirector/indirection.rb
@@ -5,13 +5,19 @@ require File.dirname(__FILE__) + '/../../spec_helper'
require 'puppet/indirector'
describe Puppet::Indirector::Indirection, " when initializing" do
+ it "should keep a reference to the indirecting model" do
+ model = mock 'model'
+ @indirection = Puppet::Indirector::Indirection.new(model, :myind)
+ @indirection.model.should equal(model)
+ end
+
it "should set the name" do
- @indirection = Puppet::Indirector::Indirection.new(:myind)
+ @indirection = Puppet::Indirector::Indirection.new(mock('model'), :myind)
@indirection.name.should == :myind
end
it "should require indirections to have unique names" do
- @indirection = Puppet::Indirector::Indirection.new(:test)
+ @indirection = Puppet::Indirector::Indirection.new(mock('model'), :test)
proc { Puppet::Indirector::Indirection.new(:test) }.should raise_error(ArgumentError)
end
@@ -22,7 +28,7 @@ end
describe Puppet::Indirector::Indirection, " when managing indirection instances" do
it "should allow an indirection to be retrieved by name" do
- @indirection = Puppet::Indirector::Indirection.new(:test)
+ @indirection = Puppet::Indirector::Indirection.new(mock('model'), :test)
Puppet::Indirector::Indirection.instance(:test).should equal(@indirection)
end
@@ -37,7 +43,7 @@ end
describe Puppet::Indirector::Indirection, " when choosing terminus types" do
before do
- @indirection = Puppet::Indirector::Indirection.new(:test)
+ @indirection = Puppet::Indirector::Indirection.new(mock('model'), :test)
@terminus = mock 'terminus'
@terminus_class = stub 'terminus class', :new => @terminus
end
@@ -82,7 +88,7 @@ end
describe Puppet::Indirector::Indirection, " when managing terminus instances" do
before do
- @indirection = Puppet::Indirector::Indirection.new(:test)
+ @indirection = Puppet::Indirector::Indirection.new(mock('model'), :test)
@terminus = mock 'terminus'
@terminus_class = mock 'terminus class'
Puppet::Indirector::Terminus.stubs(:terminus_class).with(:test, :foo).returns(@terminus_class)
@@ -111,7 +117,7 @@ describe Puppet::Indirector::Indirection, " when managing terminus instances" do
it "should not create a terminus instance until one is actually needed" do
Puppet::Indirector.expects(:terminus).never
- indirection = Puppet::Indirector::Indirection.new(:lazytest)
+ indirection = Puppet::Indirector::Indirection.new(mock('model'), :lazytest)
end
after do
@@ -122,7 +128,7 @@ end
describe Puppet::Indirector::Indirection do
before do
- @indirection = Puppet::Indirector::Indirection.new(:test)
+ @indirection = Puppet::Indirector::Indirection.new(mock('model'), :test)
@terminus = mock 'terminus'
@indirection.stubs(:terminus).returns(@terminus)
end
diff --git a/spec/unit/indirector/ldap.rb b/spec/unit/indirector/ldap.rb
new file mode 100755
index 000000000..a936936bc
--- /dev/null
+++ b/spec/unit/indirector/ldap.rb
@@ -0,0 +1,147 @@
+#!/usr/bin/env ruby
+
+require File.dirname(__FILE__) + '/../../spec_helper'
+
+require 'puppet/indirector/ldap'
+
+describe Puppet::Indirector::Ldap, " when searching ldap" do
+ before do
+ @indirection = mock 'indirection'
+ Puppet::Indirector::Indirection.stubs(:instance).returns(@indirection)
+ @ldap_class = Class.new(Puppet::Indirector::Ldap) do
+ def self.to_s
+ "Testing"
+ end
+ end
+
+ @connection = mock 'ldap'
+
+ @searcher = @ldap_class.new
+
+ # Stub everything, and we can selectively replace with an expect as
+ # we need to for testing.
+ @searcher.stubs(:connection).returns(@connection)
+ @searcher.stubs(:search_filter).returns(:filter)
+ @searcher.stubs(:search_base).returns(:base)
+ @searcher.stubs(:process)
+ end
+
+ it "should call the ldapsearch method with the name being searched for" do
+ @searcher.expects(:ldapsearch).with("yay")
+ @searcher.find "yay"
+ end
+
+ it "should fail if no block is passed to the ldapsearch method" do
+ proc { @searcher.ldapsearch("blah") }.should raise_error(ArgumentError)
+ end
+
+ it "should use the results of the ldapbase method as the ldap search base" do
+ @searcher.stubs(:search_base).returns("mybase")
+ @connection.expects(:search).with do |*args|
+ args[0].should == "mybase"
+ true
+ end
+ @searcher.find "yay"
+ end
+
+ it "should default to the value of the :search_base setting as the result of the ldapbase method" do
+ Puppet.expects(:[]).with(:ldapbase).returns("myldapbase")
+ searcher = @ldap_class.new
+ searcher.search_base.should == "myldapbase"
+ end
+
+ it "should use the results of the :search_attributes method as the list of attributes to return" do
+ @searcher.stubs(:search_attributes).returns(:myattrs)
+ @connection.expects(:search).with do |*args|
+ args[3].should == :myattrs
+ true
+ end
+ @searcher.find "yay"
+ end
+
+ it "should use the results of the :search_filter method as the search filter" do
+ @searcher.stubs(:search_filter).with("yay").returns("yay's filter")
+ @connection.expects(:search).with do |*args|
+ args[2].should == "yay's filter"
+ true
+ end
+ @searcher.find "yay"
+ end
+
+ it "should use depth 2 when searching" do
+ @connection.expects(:search).with do |*args|
+ args[1].should == 2
+ true
+ end
+ @searcher.find "yay"
+ end
+
+ it "should call process() on the first found entry" do
+ @connection.expects(:search).yields("myresult")
+ @searcher.expects(:process).with("myresult")
+ @searcher.find "yay"
+ end
+
+ it "should reconnect and retry the search if there is a failure" do
+ run = false
+ @connection.stubs(:search).with do |*args|
+ if run
+ true
+ else
+ run = true
+ raise "failed"
+ end
+ end.yields("myresult")
+ @searcher.expects(:process).with("myresult")
+
+ @searcher.find "yay"
+ end
+
+ it "should not reconnect on failure more than once" do
+ count = 0
+ @connection.stubs(:search).with do |*args|
+ count += 1
+ raise ArgumentError, "yay"
+ end
+ proc { @searcher.find("whatever") }.should raise_error(Puppet::Error)
+ count.should == 2
+ end
+
+ it "should return true if an entry is found" do
+ @connection.expects(:search).yields("result")
+ @searcher.ldapsearch("whatever") { |r| }.should be_true
+ end
+end
+
+describe Puppet::Indirector::Ldap, " when connecting to ldap" do
+ confine "LDAP is not available" => Puppet.features.ldap?
+ confine "No LDAP test data for networks other than Luke's" => Facter.value(:domain) == "madstop.com"
+
+ it "should only create the ldap connection when asked for it the first time"
+
+ it "should throw an exception if it cannot connect to LDAP"
+
+ it "should use SSL when the :ldapssl setting is true"
+
+ it "should connect to the server specified in the :ldapserver setting"
+
+ it "should use the port specified in the :ldapport setting"
+
+ it "should use protocol version 3"
+
+ it "should follow referrals"
+
+ it "should use the user specified in the :ldapuser setting"
+
+ it "should use the password specified in the :ldappassord setting"
+
+ it "should have an ldap method that returns an LDAP connection object"
+
+ it "should fail when LDAP support is missing"
+end
+
+describe Puppet::Indirector::Ldap, " when reconnecting to ldap" do
+ confine "Not running on culain as root" => (Puppet::Util::SUIDManager.uid == 0 and Facter.value("hostname") == "culain")
+
+ it "should reconnect to ldap when connections are lost"
+end
diff --git a/spec/unit/indirector/ldap/node.rb b/spec/unit/indirector/ldap/node.rb
new file mode 100755
index 000000000..edaf77e92
--- /dev/null
+++ b/spec/unit/indirector/ldap/node.rb
@@ -0,0 +1,84 @@
+#!/usr/bin/env ruby
+
+require File.dirname(__FILE__) + '/../../../spec_helper'
+
+require 'puppet/indirector/ldap/node'
+
+describe Puppet::Indirector::Ldap::Node, " when searching for nodes" do
+ before do
+ @searcher = Puppet::Indirector::Ldap::Node.new
+ end
+
+ it "should return the value of the :ldapclassattrs split on commas as the class attributes" do
+ Puppet.stubs(:[]).with(:ldapclassattrs).returns("one,two")
+ @searcher.class_attributes.should == %w{one two}
+ end
+
+ it "should return nil as the parent attribute if the :ldapparentattr is set to an empty string" do
+ Puppet.stubs(:[]).with(:ldapparentattr).returns("")
+ @searcher.parent_attribute.should be_nil
+ end
+
+ it "should return the value of the :ldapparentattr as the parent attribute" do
+ Puppet.stubs(:[]).with(:ldapparentattr).returns("pere")
+ @searcher.parent_attribute.should == "pere"
+ end
+
+ it "should use the value of the :ldapstring as the search filter" do
+ Puppet.stubs(:[]).with(:ldapstring).returns("mystring")
+ @searcher.search_filter("testing").should == "mystring"
+ end
+
+ it "should replace '%s' with the node name in the search filter if it is present" do
+ Puppet.stubs(:[]).with(:ldapstring).returns("my%sstring")
+ @searcher.search_filter("testing").should == "mytestingstring"
+ end
+
+ it "should not modify the global :ldapstring when replacing '%s' in the search filter" do
+ filter = mock 'filter'
+ filter.expects(:include?).with("%s").returns(true)
+ filter.expects(:gsub).with("%s", "testing").returns("mynewstring")
+ Puppet.stubs(:[]).with(:ldapstring).returns(filter)
+ @searcher.search_filter("testing").should == "mynewstring"
+ end
+end
+
+describe Puppet::Indirector::Ldap::Node, " when deciding attributes to search for" do
+ before do
+ @searcher = Puppet::Indirector::Ldap::Node.new
+ end
+
+ it "should use 'nil' if the :ldapattrs setting is 'all'" do
+ Puppet.stubs(:[]).with(:ldapattrs).returns("all")
+ @searcher.search_attributes.should be_nil
+ end
+
+ it "should split the value of :ldapattrs on commas and use the result as the attribute list" do
+ Puppet.stubs(:[]).with(:ldapattrs).returns("one,two")
+ @searcher.stubs(:class_attributes).returns([])
+ @searcher.stubs(:parent_attribute).returns(nil)
+ @searcher.search_attributes.should == %w{one two}
+ end
+
+ it "should add the class attributes to the search attributes if not returning all attributes" do
+ Puppet.stubs(:[]).with(:ldapattrs).returns("one,two")
+ @searcher.stubs(:class_attributes).returns(%w{three four})
+ @searcher.stubs(:parent_attribute).returns(nil)
+ # Sort them so i don't have to care about return order
+ @searcher.search_attributes.sort.should == %w{one two three four}.sort
+ end
+
+ it "should add the parent attribute to the search attributes if not returning all attributes" do
+ Puppet.stubs(:[]).with(:ldapattrs).returns("one,two")
+ @searcher.stubs(:class_attributes).returns([])
+ @searcher.stubs(:parent_attribute).returns("parent")
+ @searcher.search_attributes.sort.should == %w{one two parent}.sort
+ end
+
+ it "should not add nil parent attributes to the search attributes" do
+ Puppet.stubs(:[]).with(:ldapattrs).returns("one,two")
+ @searcher.stubs(:class_attributes).returns([])
+ @searcher.stubs(:parent_attribute).returns(nil)
+ @searcher.search_attributes.should == %w{one two}
+ end
+end
diff --git a/spec/unit/indirector/node/external.rb b/spec/unit/indirector/node/external.rb
deleted file mode 100755
index c64a6f6e2..000000000
--- a/spec/unit/indirector/node/external.rb
+++ /dev/null
@@ -1,119 +0,0 @@
-#!/usr/bin/env ruby
-
-require File.dirname(__FILE__) + '/../../../spec_helper'
-
-require 'yaml'
-require 'puppet/indirector'
-
-describe Puppet::Indirector.terminus(:node, :external), " when searching for nodes" do
- require 'puppet/node'
-
- before do
- Puppet.config[:external_nodes] = "/yay/ness"
- @searcher = Puppet::Indirector.terminus(:node, :external).new
-
- # Set the searcher up so that we do not need to actually call the
- # external script.
- @searcher.meta_def(:execute) do |command|
- name = command.last.chomp
- result = {}
-
- if name =~ /a/
- result[:parameters] = {'one' => command.last + '1', 'two' => command.last + '2'}
- end
-
- if name =~ /p/
- result['classes'] = [1,2,3].collect { |n| command.last + n.to_s }
- end
-
- return YAML.dump(result)
- end
- end
-
- it "should throw an exception if the node_source is external but no external node command is set" do
- Puppet[:external_nodes] = "none"
- proc { @searcher.find("foo") }.should raise_error(ArgumentError)
- end
-
- it "should throw an exception if the external node source is not fully qualified" do
- Puppet[:external_nodes] = "mycommand"
- proc { @searcher.find("foo") }.should raise_error(ArgumentError)
- end
-
- it "should execute the command with the node name as the only argument" do
- command = [Puppet[:external_nodes], "yay"]
- @searcher.expects(:execute).with(command).returns("")
- @searcher.find("yay")
- end
-
- it "should return a node object" do
- @searcher.find("apple").should be_instance_of(Puppet::Node)
- end
-
- it "should set the node's name" do
- @searcher.find("apple").name.should == "apple"
- end
-
- # If we use a name that has a 'p' but no 'a', then our test generator
- # will return classes but no parameters.
- it "should be able to configure a node's classes" do
- node = @searcher.find("plum")
- node.classes.should == %w{plum1 plum2 plum3}
- node.parameters.should == {}
- end
-
- # If we use a name that has an 'a' but no 'p', then our test generator
- # will return parameters but no classes.
- it "should be able to configure a node's parameters" do
- node = @searcher.find("guava")
- node.classes.should == []
- node.parameters.should == {"one" => "guava1", "two" => "guava2"}
- end
-
- it "should be able to configure a node's classes and parameters" do
- node = @searcher.find("apple")
- node.classes.should == %w{apple1 apple2 apple3}
- node.parameters.should == {"one" => "apple1", "two" => "apple2"}
- end
-
- it "should merge node facts with returned parameters" do
- facts = Puppet::Node::Facts.new("apple", "three" => "four")
- Puppet::Node::Facts.expects(:find).with("apple").returns(facts)
- node = @searcher.find("apple")
- node.parameters["three"].should == "four"
- end
-
- it "should return nil when it cannot find the node" do
- @searcher.find("honeydew").should be_nil
- end
-
- # Make sure a nodesearch with arguments works
- def test_nodesearch_external_arguments
- mapper = mk_node_mapper
- Puppet[:external_nodes] = "#{mapper} -s something -p somethingelse"
- searcher = mk_searcher(:external)
- node = nil
- assert_nothing_raised do
- node = searcher.nodesearch("apple")
- end
- assert_instance_of(SimpleNode, node, "did not create node")
- end
-
- # A wrapper test, to make sure we're correctly calling the external search method.
- def test_nodesearch_external_functional
- mapper = mk_node_mapper
- searcher = mk_searcher(:external)
-
- Puppet[:external_nodes] = mapper
-
- node = nil
- assert_nothing_raised do
- node = searcher.nodesearch("apple")
- end
- assert_instance_of(SimpleNode, node, "did not create node")
- end
-
- after do
- Puppet.config.clear
- end
-end
diff --git a/spec/unit/indirector/node/ldap.rb b/spec/unit/indirector/node/ldap.rb
deleted file mode 100755
index e4b0cd7d4..000000000
--- a/spec/unit/indirector/node/ldap.rb
+++ /dev/null
@@ -1,243 +0,0 @@
-#!/usr/bin/env ruby
-
-require File.dirname(__FILE__) + '/../../../spec_helper'
-
-require 'yaml'
-require 'puppet/indirector'
-
-describe Puppet::Indirector.terminus(:node, :ldap), " when searching for nodes" do
- require 'puppet/node'
-
- def setup
- Puppet.config[:external_nodes] = "/yay/ness"
- @searcher = Puppet::Indirector.terminus(:node, :ldap).new
- nodetable = {}
- @nodetable = nodetable
- # Override the ldapsearch definition, so we don't have to actually set it up.
- @searcher.meta_def(:ldapsearch) do |name|
- nodetable[name]
- end
- end
-
- it "should return nil for hosts that cannot be found" do
- @searcher.find("foo").should be_nil
- end
-
- it "should return Puppet::Node instances" do
- @nodetable["foo"] = [nil, %w{}, {}]
- @searcher.find("foo").should be_instance_of(Puppet::Node)
- end
-
- it "should set the node name" do
- @nodetable["foo"] = [nil, %w{}, {}]
- @searcher.find("foo").name.should == "foo"
- end
-
- it "should set the classes" do
- @nodetable["foo"] = [nil, %w{one two}, {}]
- @searcher.find("foo").classes.should == %w{one two}
- end
-
- it "should set the parameters" do
- @nodetable["foo"] = [nil, %w{}, {"one" => "two"}]
- @searcher.find("foo").parameters.should == {"one" => "two"}
- end
-
- it "should set classes and parameters from the parent node" do
- @nodetable["foo"] = ["middle", %w{one two}, {"one" => "two"}]
- @nodetable["middle"] = [nil, %w{three four}, {"three" => "four"}]
- node = @searcher.find("foo")
- node.classes.sort.should == %w{one two three four}.sort
- node.parameters.should == {"one" => "two", "three" => "four"}
- end
-
- it "should prefer child parameters to parent parameters" do
- @nodetable["foo"] = ["middle", %w{}, {"one" => "two"}]
- @nodetable["middle"] = [nil, %w{}, {"one" => "four"}]
- @searcher.find("foo").parameters["one"].should == "two"
- end
-
- it "should recurse indefinitely through parent relationships" do
- @nodetable["foo"] = ["middle", %w{one two}, {"one" => "two"}]
- @nodetable["middle"] = ["top", %w{three four}, {"three" => "four"}]
- @nodetable["top"] = [nil, %w{five six}, {"five" => "six"}]
- node = @searcher.find("foo")
- node.parameters.should == {"one" => "two", "three" => "four", "five" => "six"}
- node.classes.sort.should == %w{one two three four five six}.sort
- end
-
- # This can stay in the main test suite because it doesn't actually use ldapsearch,
- # it just overrides the method so it behaves as though it were hitting ldap.
- def test_ldap_nodesearch
-
- # Make sure we get nothing for nonexistent hosts
- node = nil
- assert_nothing_raised do
- node = searcher.nodesearch("nosuchhost")
- end
-
- assert_nil(node, "Got a node for a non-existent host")
-
- # Now add a base node with some classes and parameters
- nodetable["base"] = [nil, %w{one two}, {"base" => "true"}]
-
- assert_nothing_raised do
- node = searcher.nodesearch("base")
- end
-
- assert_instance_of(SimpleNode, node, "Did not get node from ldap nodesearch")
- assert_equal("base", node.name, "node name was not set")
-
- assert_equal(%w{one two}, node.classes, "node classes were not set")
- assert_equal({"base" => "true"}, node.parameters, "node parameters were not set")
-
- # Now use a different with this as the base
- nodetable["middle"] = ["base", %w{three}, {"center" => "boo"}]
- assert_nothing_raised do
- node = searcher.nodesearch("middle")
- end
-
- assert_instance_of(SimpleNode, node, "Did not get node from ldap nodesearch")
- assert_equal("middle", node.name, "node name was not set")
-
- assert_equal(%w{one two three}.sort, node.classes.sort, "node classes were not set correctly with a parent node")
- assert_equal({"base" => "true", "center" => "boo"}, node.parameters, "node parameters were not set correctly with a parent node")
-
- # And one further, to make sure we fully recurse
- nodetable["top"] = ["middle", %w{four five}, {"master" => "far"}]
- assert_nothing_raised do
- node = searcher.nodesearch("top")
- end
-
- assert_instance_of(SimpleNode, node, "Did not get node from ldap nodesearch")
- assert_equal("top", node.name, "node name was not set")
-
- assert_equal(%w{one two three four five}.sort, node.classes.sort, "node classes were not set correctly with the top node")
- assert_equal({"base" => "true", "center" => "boo", "master" => "far"}, node.parameters, "node parameters were not set correctly with the top node")
- end
-end
-
-describe Puppet::Indirector.terminus(:node, :ldap), " when interacting with ldap" do
- confine "LDAP is not available" => Puppet.features.ldap?
- confine "No LDAP test data for networks other than Luke's" => Facter.value(:domain) == "madstop.com"
-
- def ldapconnect
-
- @ldap = LDAP::Conn.new("ldap", 389)
- @ldap.set_option( LDAP::LDAP_OPT_PROTOCOL_VERSION, 3 )
- @ldap.simple_bind("", "")
-
- return @ldap
- end
-
- def ldaphost(name)
- node = Puppet::Node.new(name)
- parent = nil
- found = false
- @ldap.search( "ou=hosts, dc=madstop, dc=com", 2,
- "(&(objectclass=puppetclient)(cn=%s))" % name
- ) do |entry|
- node.classes = entry.vals("puppetclass") || []
- node.parameters = entry.to_hash.inject({}) do |hash, ary|
- if ary[1].length == 1
- hash[ary[0]] = ary[1].shift
- else
- hash[ary[0]] = ary[1]
- end
- hash
- end
- parent = node.parameters["parentnode"]
- found = true
- end
- raise "Could not find node %s" % name unless found
-
- return node, parent
- end
-
- it "should have tests" do
- raise ArgumentError
- end
-
- def test_ldapsearch
- Puppet[:ldapbase] = "ou=hosts, dc=madstop, dc=com"
- Puppet[:ldapnodes] = true
-
- searcher = Object.new
- searcher.extend(Node.node_source(:ldap))
-
- ldapconnect()
-
- # Make sure we get nil and nil back when we search for something missing
- parent, classes, parameters = nil
- assert_nothing_raised do
- parent, classes, parameters = searcher.ldapsearch("nosuchhost")
- end
-
- assert_nil(parent, "Got a parent for a non-existent host")
- assert_nil(classes, "Got classes for a non-existent host")
-
- # Make sure we can find 'culain' in ldap
- assert_nothing_raised do
- parent, classes, parameters = searcher.ldapsearch("culain")
- end
-
- node, realparent = ldaphost("culain")
- assert_equal(realparent, parent, "did not get correct parent node from ldap")
- assert_equal(node.classes, classes, "did not get correct ldap classes from ldap")
- assert_equal(node.parameters, parameters, "did not get correct ldap parameters from ldap")
-
- # Now compare when we specify the attributes to get.
- Puppet[:ldapattrs] = "cn"
- assert_nothing_raised do
- parent, classes, parameters = searcher.ldapsearch("culain")
- end
- assert_equal(realparent, parent, "did not get correct parent node from ldap")
- assert_equal(node.classes, classes, "did not get correct ldap classes from ldap")
-
- list = %w{cn puppetclass parentnode dn}
- should = node.parameters.inject({}) { |h, a| h[a[0]] = a[1] if list.include?(a[0]); h }
- assert_equal(should, parameters, "did not get correct ldap parameters from ldap")
- end
-end
-
-describe Puppet::Indirector.terminus(:node, :ldap), " when connecting to ldap" do
- confine "Not running on culain as root" => (Puppet::Util::SUIDManager.uid == 0 and Facter.value("hostname") == "culain")
-
- it "should have tests" do
- raise ArgumentError
- end
-
- def test_ldapreconnect
- Puppet[:ldapbase] = "ou=hosts, dc=madstop, dc=com"
- Puppet[:ldapnodes] = true
-
- searcher = Object.new
- searcher.extend(Node.node_source(:ldap))
- hostname = "culain.madstop.com"
-
- # look for our host
- assert_nothing_raised {
- parent, classes = searcher.nodesearch(hostname)
- }
-
- # Now restart ldap
- system("/etc/init.d/slapd restart 2>/dev/null >/dev/null")
- sleep(1)
-
- # and look again
- assert_nothing_raised {
- parent, classes = searcher.nodesearch(hostname)
- }
-
- # Now stop ldap
- system("/etc/init.d/slapd stop 2>/dev/null >/dev/null")
- cleanup do
- system("/etc/init.d/slapd start 2>/dev/null >/dev/null")
- end
-
- # And make sure we actually fail here
- assert_raise(Puppet::Error) {
- parent, classes = searcher.nodesearch(hostname)
- }
- end
-end
diff --git a/spec/unit/indirector/node/none.rb b/spec/unit/indirector/node/none.rb
deleted file mode 100755
index 2329cdfbb..000000000
--- a/spec/unit/indirector/node/none.rb
+++ /dev/null
@@ -1,32 +0,0 @@
-#!/usr/bin/env ruby
-
-require File.dirname(__FILE__) + '/../../../spec_helper'
-require 'puppet/indirector'
-require 'puppet/node/facts'
-
-describe Puppet::Indirector.terminus(:node, :none), " when searching for nodes" do
- before do
- Puppet.config[:node_source] = "none"
- @searcher = Puppet::Indirector.terminus(:node, :none).new
- end
-
- it "should create a node instance" do
- @searcher.find("yay").should be_instance_of(Puppet::Node)
- end
-
- it "should create a new node with the correct name" do
- @searcher.find("yay").name.should == "yay"
- end
-
- it "should merge the node's facts" do
- facts = Puppet::Node::Facts.new("yay", "one" => "two", "three" => "four")
- Puppet::Node::Facts.expects(:find).with("yay").returns(facts)
- node = @searcher.find("yay")
- node.parameters["one"].should == "two"
- node.parameters["three"].should == "four"
- end
-
- after do
- Puppet.config.clear
- end
-end
diff --git a/spec/unit/indirector/null.rb b/spec/unit/indirector/null.rb
new file mode 100755
index 000000000..9e1dcb07c
--- /dev/null
+++ b/spec/unit/indirector/null.rb
@@ -0,0 +1,27 @@
+#!/usr/bin/env ruby
+
+require File.dirname(__FILE__) + '/../../spec_helper'
+require 'puppet/indirector/null'
+
+describe Puppet::Indirector::Null do
+ before do
+ Puppet::Indirector::Terminus.stubs(:register_terminus_class)
+ @model = mock 'model'
+ @indirection = stub 'indirection', :name => :mystuff, :register_terminus_type => nil, :model => @model
+ Puppet::Indirector::Indirection.stubs(:instance).returns(@indirection)
+
+ @null_class = Class.new(Puppet::Indirector::Null) do
+ def self.to_s
+ "Testing"
+ end
+ end
+
+ @searcher = @null_class.new
+ end
+
+ it "should return return an instance of the indirected model" do
+ object = mock 'object'
+ @model.expects(:new).with("yay").returns object
+ @searcher.find("yay").should equal(object)
+ end
+end
diff --git a/spec/unit/indirector/null/node.rb b/spec/unit/indirector/null/node.rb
new file mode 100755
index 000000000..c589e5820
--- /dev/null
+++ b/spec/unit/indirector/null/node.rb
@@ -0,0 +1,18 @@
+#!/usr/bin/env ruby
+
+require File.dirname(__FILE__) + '/../../../spec_helper'
+
+require 'puppet/indirector/null/node'
+
+describe Puppet::Indirector::Null::Node do
+ before do
+ @searcher = Puppet::Indirector::Null::Node.new
+ end
+
+ it "should call node_merge() on the returned node" do
+ node = mock 'node'
+ Puppet::Node.expects(:new).with("mynode").returns(node)
+ node.expects(:fact_merge)
+ @searcher.find("mynode")
+ end
+end
diff --git a/spec/unit/indirector/terminus.rb b/spec/unit/indirector/terminus.rb
index 08e7e6ccb..dc86cf315 100755
--- a/spec/unit/indirector/terminus.rb
+++ b/spec/unit/indirector/terminus.rb
@@ -36,6 +36,10 @@ describe Puppet::Indirector::Terminus do
@terminus.should respond_to(:terminus_type)
end
+ it "should support a class-level model attribute" do
+ @terminus.should respond_to(:model)
+ end
+
it "should accept indirection instances as its indirection" do
indirection = stub 'indirection', :is_a? => true, :register_terminus_type => nil
proc { @terminus.indirection = indirection }.should_not raise_error
@@ -177,6 +181,11 @@ describe Puppet::Indirector::Terminus, " when creating terminus classes" do
it "should set the subclass's name to the indirection name" do
@terminus.name.should == :myindirection
end
+
+ it "should set the subclass's model to the indirection model" do
+ @indirection.expects(:model).returns :yay
+ @terminus.model.should == :yay
+ end
end
describe Puppet::Indirector::Terminus, " when a terminus instance" do
@@ -209,4 +218,9 @@ describe Puppet::Indirector::Terminus, " when a terminus instance" do
it "should set the instances's type to the abstract terminus type's name" do
@terminus.terminus_type.should == :abstract
end
+
+ it "should set the instances's model to the indirection's model" do
+ @indirection.expects(:model).returns :yay
+ @terminus.model.should == :yay
+ end
end