diff options
author | Christopher Speller <crspeller@gmail.com> | 2018-04-16 05:37:14 -0700 |
---|---|---|
committer | Joram Wilander <jwawilander@gmail.com> | 2018-04-16 08:37:14 -0400 |
commit | 6e2cb00008cbf09e556b00f87603797fcaa47e09 (patch) | |
tree | 3c0eb55ff4226a3f024aad373140d1fb860a6404 /vendor/github.com/go-ldap/ldap/conn_test.go | |
parent | bf24f51c4e1cc6286885460672f7f449e8c6f5ef (diff) | |
download | chat-6e2cb00008cbf09e556b00f87603797fcaa47e09.tar.gz chat-6e2cb00008cbf09e556b00f87603797fcaa47e09.tar.bz2 chat-6e2cb00008cbf09e556b00f87603797fcaa47e09.zip |
Depenancy upgrades and movign to dep. (#8630)
Diffstat (limited to 'vendor/github.com/go-ldap/ldap/conn_test.go')
-rw-r--r-- | vendor/github.com/go-ldap/ldap/conn_test.go | 336 |
1 files changed, 0 insertions, 336 deletions
diff --git a/vendor/github.com/go-ldap/ldap/conn_test.go b/vendor/github.com/go-ldap/ldap/conn_test.go deleted file mode 100644 index 488754d16..000000000 --- a/vendor/github.com/go-ldap/ldap/conn_test.go +++ /dev/null @@ -1,336 +0,0 @@ -package ldap - -import ( - "bytes" - "errors" - "io" - "net" - "net/http" - "net/http/httptest" - "runtime" - "sync" - "testing" - "time" - - "gopkg.in/asn1-ber.v1" -) - -func TestUnresponsiveConnection(t *testing.T) { - // The do-nothing server that accepts requests and does nothing - ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - })) - defer ts.Close() - c, err := net.Dial(ts.Listener.Addr().Network(), ts.Listener.Addr().String()) - if err != nil { - t.Fatalf("error connecting to localhost tcp: %v", err) - } - - // Create an Ldap connection - conn := NewConn(c, false) - conn.SetTimeout(time.Millisecond) - conn.Start() - defer conn.Close() - - // Mock a packet - packet := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "LDAP Request") - packet.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagInteger, conn.nextMessageID(), "MessageID")) - bindRequest := ber.Encode(ber.ClassApplication, ber.TypeConstructed, ApplicationBindRequest, nil, "Bind Request") - bindRequest.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagInteger, 3, "Version")) - packet.AppendChild(bindRequest) - - // Send packet and test response - msgCtx, err := conn.sendMessage(packet) - if err != nil { - t.Fatalf("error sending message: %v", err) - } - defer conn.finishMessage(msgCtx) - - packetResponse, ok := <-msgCtx.responses - if !ok { - t.Fatalf("no PacketResponse in response channel") - } - packet, err = packetResponse.ReadPacket() - if err == nil { - t.Fatalf("expected timeout error") - } - if err.Error() != "ldap: connection timed out" { - t.Fatalf("unexpected error: %v", err) - } -} - -// TestFinishMessage tests that we do not enter deadlock when a goroutine makes -// a request but does not handle all responses from the server. -func TestFinishMessage(t *testing.T) { - ptc := newPacketTranslatorConn() - defer ptc.Close() - - conn := NewConn(ptc, false) - conn.Start() - - // Test sending 5 different requests in series. Ensure that we can - // get a response packet from the underlying connection and also - // ensure that we can gracefully ignore unhandled responses. - for i := 0; i < 5; i++ { - t.Logf("serial request %d", i) - // Create a message and make sure we can receive responses. - msgCtx := testSendRequest(t, ptc, conn) - testReceiveResponse(t, ptc, msgCtx) - - // Send a few unhandled responses and finish the message. - testSendUnhandledResponsesAndFinish(t, ptc, conn, msgCtx, 5) - t.Logf("serial request %d done", i) - } - - // Test sending 5 different requests in parallel. - var wg sync.WaitGroup - for i := 0; i < 5; i++ { - wg.Add(1) - go func(i int) { - defer wg.Done() - t.Logf("parallel request %d", i) - // Create a message and make sure we can receive responses. - msgCtx := testSendRequest(t, ptc, conn) - testReceiveResponse(t, ptc, msgCtx) - - // Send a few unhandled responses and finish the message. - testSendUnhandledResponsesAndFinish(t, ptc, conn, msgCtx, 5) - t.Logf("parallel request %d done", i) - }(i) - } - wg.Wait() - - // We cannot run Close() in a defer because t.FailNow() will run it and - // it will block if the processMessage Loop is in a deadlock. - conn.Close() -} - -func testSendRequest(t *testing.T, ptc *packetTranslatorConn, conn *Conn) (msgCtx *messageContext) { - var msgID int64 - runWithTimeout(t, time.Second, func() { - msgID = conn.nextMessageID() - }) - - requestPacket := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "LDAP Request") - requestPacket.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagInteger, msgID, "MessageID")) - - var err error - - runWithTimeout(t, time.Second, func() { - msgCtx, err = conn.sendMessage(requestPacket) - if err != nil { - t.Fatalf("unable to send request message: %s", err) - } - }) - - // We should now be able to get this request packet out from the other - // side. - runWithTimeout(t, time.Second, func() { - if _, err = ptc.ReceiveRequest(); err != nil { - t.Fatalf("unable to receive request packet: %s", err) - } - }) - - return msgCtx -} - -func testReceiveResponse(t *testing.T, ptc *packetTranslatorConn, msgCtx *messageContext) { - // Send a mock response packet. - responsePacket := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "LDAP Response") - responsePacket.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagInteger, msgCtx.id, "MessageID")) - - runWithTimeout(t, time.Second, func() { - if err := ptc.SendResponse(responsePacket); err != nil { - t.Fatalf("unable to send response packet: %s", err) - } - }) - - // We should be able to receive the packet from the connection. - runWithTimeout(t, time.Second, func() { - if _, ok := <-msgCtx.responses; !ok { - t.Fatal("response channel closed") - } - }) -} - -func testSendUnhandledResponsesAndFinish(t *testing.T, ptc *packetTranslatorConn, conn *Conn, msgCtx *messageContext, numResponses int) { - // Send a mock response packet. - responsePacket := ber.Encode(ber.ClassUniversal, ber.TypeConstructed, ber.TagSequence, nil, "LDAP Response") - responsePacket.AppendChild(ber.NewInteger(ber.ClassUniversal, ber.TypePrimitive, ber.TagInteger, msgCtx.id, "MessageID")) - - // Send extra responses but do not attempt to receive them on the - // client side. - for i := 0; i < numResponses; i++ { - runWithTimeout(t, time.Second, func() { - if err := ptc.SendResponse(responsePacket); err != nil { - t.Fatalf("unable to send response packet: %s", err) - } - }) - } - - // Finally, attempt to finish this message. - runWithTimeout(t, time.Second, func() { - conn.finishMessage(msgCtx) - }) -} - -func runWithTimeout(t *testing.T, timeout time.Duration, f func()) { - done := make(chan struct{}) - go func() { - f() - close(done) - }() - - select { - case <-done: // Success! - case <-time.After(timeout): - _, file, line, _ := runtime.Caller(1) - t.Fatalf("%s:%d timed out", file, line) - } -} - -// packetTranslatorConn is a helpful type which can be used with various tests -// in this package. It implements the net.Conn interface to be used as an -// underlying connection for a *ldap.Conn. Most methods are no-ops but the -// Read() and Write() methods are able to translate ber-encoded packets for -// testing LDAP requests and responses. -// -// Test cases can simulate an LDAP server sending a response by calling the -// SendResponse() method with a ber-encoded LDAP response packet. Test cases -// can simulate an LDAP server receiving a request from a client by calling the -// ReceiveRequest() method which returns a ber-encoded LDAP request packet. -type packetTranslatorConn struct { - lock sync.Mutex - isClosed bool - - responseCond sync.Cond - requestCond sync.Cond - - responseBuf bytes.Buffer - requestBuf bytes.Buffer -} - -var errPacketTranslatorConnClosed = errors.New("connection closed") - -func newPacketTranslatorConn() *packetTranslatorConn { - conn := &packetTranslatorConn{} - conn.responseCond = sync.Cond{L: &conn.lock} - conn.requestCond = sync.Cond{L: &conn.lock} - - return conn -} - -// Read is called by the reader() loop to receive response packets. It will -// block until there are more packet bytes available or this connection is -// closed. -func (c *packetTranslatorConn) Read(b []byte) (n int, err error) { - c.lock.Lock() - defer c.lock.Unlock() - - for !c.isClosed { - // Attempt to read data from the response buffer. If it fails - // with an EOF, wait and try again. - n, err = c.responseBuf.Read(b) - if err != io.EOF { - return n, err - } - - c.responseCond.Wait() - } - - return 0, errPacketTranslatorConnClosed -} - -// SendResponse writes the given response packet to the response buffer for -// this connection, signalling any goroutine waiting to read a response. -func (c *packetTranslatorConn) SendResponse(packet *ber.Packet) error { - c.lock.Lock() - defer c.lock.Unlock() - - if c.isClosed { - return errPacketTranslatorConnClosed - } - - // Signal any goroutine waiting to read a response. - defer c.responseCond.Broadcast() - - // Writes to the buffer should always succeed. - c.responseBuf.Write(packet.Bytes()) - - return nil -} - -// Write is called by the processMessages() loop to send request packets. -func (c *packetTranslatorConn) Write(b []byte) (n int, err error) { - c.lock.Lock() - defer c.lock.Unlock() - - if c.isClosed { - return 0, errPacketTranslatorConnClosed - } - - // Signal any goroutine waiting to read a request. - defer c.requestCond.Broadcast() - - // Writes to the buffer should always succeed. - return c.requestBuf.Write(b) -} - -// ReceiveRequest attempts to read a request packet from this connection. It -// will block until it is able to read a full request packet or until this -// connection is closed. -func (c *packetTranslatorConn) ReceiveRequest() (*ber.Packet, error) { - c.lock.Lock() - defer c.lock.Unlock() - - for !c.isClosed { - // Attempt to parse a request packet from the request buffer. - // If it fails with an unexpected EOF, wait and try again. - requestReader := bytes.NewReader(c.requestBuf.Bytes()) - packet, err := ber.ReadPacket(requestReader) - switch err { - case io.EOF, io.ErrUnexpectedEOF: - c.requestCond.Wait() - case nil: - // Advance the request buffer by the number of bytes - // read to decode the request packet. - c.requestBuf.Next(c.requestBuf.Len() - requestReader.Len()) - return packet, nil - default: - return nil, err - } - } - - return nil, errPacketTranslatorConnClosed -} - -// Close closes this connection causing Read() and Write() calls to fail. -func (c *packetTranslatorConn) Close() error { - c.lock.Lock() - defer c.lock.Unlock() - - c.isClosed = true - c.responseCond.Broadcast() - c.requestCond.Broadcast() - - return nil -} - -func (c *packetTranslatorConn) LocalAddr() net.Addr { - return (*net.TCPAddr)(nil) -} - -func (c *packetTranslatorConn) RemoteAddr() net.Addr { - return (*net.TCPAddr)(nil) -} - -func (c *packetTranslatorConn) SetDeadline(t time.Time) error { - return nil -} - -func (c *packetTranslatorConn) SetReadDeadline(t time.Time) error { - return nil -} - -func (c *packetTranslatorConn) SetWriteDeadline(t time.Time) error { - return nil -} |