summaryrefslogtreecommitdiffstats
path: root/spec/unit/indirector/ldap.rb
blob: 2c4060c4d088de82f979ad709f0ee96f15fd3319 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
#!/usr/bin/env ruby

require File.dirname(__FILE__) + '/../../spec_helper'

require 'puppet/indirector/ldap'

describe Puppet::Indirector::Ldap do
    before do
        @indirection = stub 'indirection', :name => :testing
        Puppet::Indirector::Indirection.stubs(:instance).returns(@indirection)
        @ldap_class = Class.new(Puppet::Indirector::Ldap) do
            def self.to_s
                "Testing::Mytype"
            end
        end

        @connection = mock 'ldap'

        @searcher = @ldap_class.new
    end

    describe "when searching ldap" do
        before do
            # 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)

            @request = stub 'request', :key => "yay"
        end

        it "should call the ldapsearch method with the search filter" do
            @searcher.expects(:search_filter).with("yay").returns("yay's filter")
            @searcher.expects(:ldapsearch).with("yay's filter")
            @searcher.find @request
        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 @request
        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 @request
        end

        it "should use depth 2 when searching" do
            @connection.expects(:search).with do |*args|
                args[1].should == 2
                true
            end
            @searcher.find @request
        end

        it "should call process() on the first found entry" do
            @connection.expects(:search).yields("myresult")
            @searcher.expects(:process).with("myresult")
            @searcher.find @request
        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 @request
        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(@request) }.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 "when connecting to ldap" do
        confine "LDAP is not available" => Puppet.features.ldap?

        it "should create and start a Util::Ldap::Connection instance" do
            conn = mock 'connection', :connection => "myconn", :start => nil
            Puppet::Util::Ldap::Connection.expects(:instance).returns conn

            @searcher.connection.should == "myconn"
        end

        it "should only create the ldap connection when asked for it the first time" do
            conn = mock 'connection', :connection => "myconn", :start => nil
            Puppet::Util::Ldap::Connection.expects(:instance).returns conn

            @searcher.connection
        end

        it "should cache the connection" do
            conn = mock 'connection', :connection => "myconn", :start => nil
            Puppet::Util::Ldap::Connection.expects(:instance).returns conn

            @searcher.connection.should equal(@searcher.connection)
        end
    end

    describe "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
end