require 'spec_helper' describe Net::LDAP do describe "initialize" do context "when instrumentation is configured" do before do @connection = flexmock(:connection, :close => true) flexmock(Net::LDAP::Connection).should_receive(:new).and_return(@connection) @service = MockInstrumentationService.new end subject do Net::LDAP.new \ :server => "test.mocked.com", :port => 636, :force_no_page => true, # so server capabilities are not queried :instrumentation_service => @service end it "should instrument bind" do events = @service.subscribe "bind.net_ldap" bind_result = flexmock(:bind_result, :success? => true) @connection.should_receive(:bind).with(Hash).and_return(bind_result) subject.bind.should be_true payload, result = events.pop result.should be_true payload[:bind].should == bind_result end it "should instrument search" do events = @service.subscribe "search.net_ldap" @connection.should_receive(:bind).and_return(flexmock(:bind_result, :result_code => 0)) @connection.should_receive(:search).with(Hash, Proc). yields(entry = Net::LDAP::Entry.new("uid=user1,ou=users,dc=example,dc=com")). and_return(flexmock(:search_result, :success? => true, :result_code => 0)) subject.search(:filter => "(uid=user1)").should be_true payload, result = events.pop result.should == [entry] payload[:result].should == [entry] payload[:filter].should == "(uid=user1)" end end end end describe Net::LDAP::Connection do describe "initialize" do context "when host is not responding" do before(:each) do flexmock(TCPSocket). should_receive(:new).and_raise(Errno::ECONNREFUSED) end it "should raise LdapError" do lambda { Net::LDAP::Connection.new( :server => 'test.mocked.com', :port => 636) }.should raise_error(Net::LDAP::LdapError) end end context "when host is blocking the port" do before(:each) do flexmock(TCPSocket). should_receive(:new).and_raise(SocketError) end it "should raise LdapError" do lambda { Net::LDAP::Connection.new( :server => 'test.mocked.com', :port => 636) }.should raise_error(Net::LDAP::LdapError) end end context "on other exceptions" do before(:each) do flexmock(TCPSocket). should_receive(:new).and_raise(NameError) end it "should rethrow the exception" do lambda { Net::LDAP::Connection.new( :server => 'test.mocked.com', :port => 636) }.should raise_error(NameError) end end end context "populate error messages" do before do @tcp_socket = flexmock(:connection) @tcp_socket.should_receive(:write) flexmock(TCPSocket).should_receive(:new).and_return(@tcp_socket) end subject { Net::LDAP::Connection.new(:server => 'test.mocked.com', :port => 636) } it "should get back error messages if operation fails" do ber = Net::BER::BerIdentifiedArray.new([53, "", "The provided password value was rejected by a password validator: The provided password did not contain enough characters from the character set 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'. The minimum number of characters from that set that must be present in user passwords is 1"]) ber.ber_identifier = Net::LDAP::PDU::ModifyResponse @tcp_socket.should_receive(:read_ber).and_return([2, ber]) result = subject.modify(:dn => "1", :operations => [[:replace, "mail", "something@sothsdkf.com"]]) result.should be_failure result.error_message.should == "The provided password value was rejected by a password validator: The provided password did not contain enough characters from the character set 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'. The minimum number of characters from that set that must be present in user passwords is 1" end it "shouldn't get back error messages if operation succeeds" do ber = Net::BER::BerIdentifiedArray.new([0, "", ""]) ber.ber_identifier = Net::LDAP::PDU::ModifyResponse @tcp_socket.should_receive(:read_ber).and_return([2, ber]) result = subject.modify(:dn => "1", :operations => [[:replace, "mail", "something@sothsdkf.com"]]) result.should be_success result.error_message.should == "" end end context "instrumentation" do before do @tcp_socket = flexmock(:connection) # handle write @tcp_socket.should_receive(:write) # return this mock flexmock(TCPSocket).should_receive(:new).and_return(@tcp_socket) @service = MockInstrumentationService.new end subject do Net::LDAP::Connection.new(:server => 'test.mocked.com', :port => 636, :instrumentation_service => @service) end it "should publish a write.net_ldap_connection event" do ber = Net::BER::BerIdentifiedArray.new([0, "", ""]) ber.ber_identifier = Net::LDAP::PDU::BindResult read_result = [2, ber] @tcp_socket.should_receive(:read_ber).and_return(read_result) events = @service.subscribe "write.net_ldap_connection" result = subject.bind(method: :anon) result.should be_success # a write event payload, result = events.pop payload.should have_key(:result) payload.should have_key(:content_length) end it "should publish a read.net_ldap_connection event" do ber = Net::BER::BerIdentifiedArray.new([0, "", ""]) ber.ber_identifier = Net::LDAP::PDU::BindResult read_result = [2, ber] @tcp_socket.should_receive(:read_ber).and_return(read_result) events = @service.subscribe "read.net_ldap_connection" result = subject.bind(method: :anon) result.should be_success # a read event payload, result = events.pop payload.should have_key(:result) result.should == read_result end it "should publish a bind.net_ldap_connection event" do ber = Net::BER::BerIdentifiedArray.new([0, "", ""]) ber.ber_identifier = Net::LDAP::PDU::BindResult bind_result = [2, ber] @tcp_socket.should_receive(:read_ber).and_return(bind_result) events = @service.subscribe "bind.net_ldap_connection" result = subject.bind(method: :anon) result.should be_success # a read event payload, result = events.pop payload.should have_key(:result) result.should be_success end it "should publish a search.net_ldap_connection event" do # search data search_data_ber = Net::BER::BerIdentifiedArray.new([2, [ "uid=user1,ou=OrgUnit2,ou=OrgUnitTop,dc=openldap,dc=ghe,dc=local", [ ["uid", ["user1"]] ] ]]) search_data_ber.ber_identifier = Net::LDAP::PDU::SearchReturnedData search_data = [2, search_data_ber] # search result (end of results) search_result_ber = Net::BER::BerIdentifiedArray.new([0, "", ""]) search_result_ber.ber_identifier = Net::LDAP::PDU::SearchResult search_result = [2, search_result_ber] @tcp_socket.should_receive(:read_ber).and_return(search_data). and_return(search_result) events = @service.subscribe "search.net_ldap_connection" result = subject.search(filter: "(uid=user1)") result.should be_success # a search event payload, result = events.pop payload.should have_key(:result) payload.should have_key(:filter) payload[:filter].to_s.should == "(uid=user1)" result.should be_truthy end end end