123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103 |
- package ldap
- import (
- "errors"
- "net"
- "strings"
- "testing"
- "time"
- "gopkg.in/asn1-ber.v1"
- )
- // TestNilPacket tests that nil packets don't cause a panic.
- func TestNilPacket(t *testing.T) {
- // Test for nil packet
- code, _ := getLDAPResultCode(nil)
- if code != ErrorUnexpectedResponse {
- t.Errorf("Should have an 'ErrorUnexpectedResponse' error in nil packets, got: %v", code)
- }
- // Test for nil result
- kids := []*ber.Packet{
- {}, // Unused
- nil, // Can't be nil
- }
- pack := &ber.Packet{Children: kids}
- code, _ = getLDAPResultCode(pack)
- if code != ErrorUnexpectedResponse {
- t.Errorf("Should have an 'ErrorUnexpectedResponse' error in nil packets, got: %v", code)
- }
- }
- // TestConnReadErr tests that an unexpected error reading from underlying
- // connection bubbles up to the goroutine which makes a request.
- func TestConnReadErr(t *testing.T) {
- conn := &signalErrConn{
- signals: make(chan error),
- }
- ldapConn := NewConn(conn, false)
- ldapConn.Start()
- // Make a dummy search request.
- searchReq := NewSearchRequest("dc=example,dc=com", ScopeWholeSubtree, DerefAlways, 0, 0, false, "(objectClass=*)", nil, nil)
- expectedError := errors.New("this is the error you are looking for")
- // Send the signal after a short amount of time.
- time.AfterFunc(10*time.Millisecond, func() { conn.signals <- expectedError })
- // This should block until the underlying conn gets the error signal
- // which should bubble up through the reader() goroutine, close the
- // connection, and
- _, err := ldapConn.Search(searchReq)
- if err == nil || !strings.Contains(err.Error(), expectedError.Error()) {
- t.Errorf("not the expected error: %s", err)
- }
- }
- // signalErrConn is a helpful type used with TestConnReadErr. It implements the
- // net.Conn interface to be used as a connection for the test. Most methods are
- // no-ops but the Read() method blocks until it receives a signal which it
- // returns as an error.
- type signalErrConn struct {
- signals chan error
- }
- // Read blocks until an error is sent on the internal signals channel. That
- // error is returned.
- func (c *signalErrConn) Read(b []byte) (n int, err error) {
- return 0, <-c.signals
- }
- func (c *signalErrConn) Write(b []byte) (n int, err error) {
- return len(b), nil
- }
- func (c *signalErrConn) Close() error {
- close(c.signals)
- return nil
- }
- func (c *signalErrConn) LocalAddr() net.Addr {
- return (*net.TCPAddr)(nil)
- }
- func (c *signalErrConn) RemoteAddr() net.Addr {
- return (*net.TCPAddr)(nil)
- }
- func (c *signalErrConn) SetDeadline(t time.Time) error {
- return nil
- }
- func (c *signalErrConn) SetReadDeadline(t time.Time) error {
- return nil
- }
- func (c *signalErrConn) SetWriteDeadline(t time.Time) error {
- return nil
- }
|