test/com/sun/jndi/ldap/NamingExceptionMessageTest.java

Wed, 09 Sep 2020 14:19:14 -0400

author
zgu
date
Wed, 09 Sep 2020 14:19:14 -0400
changeset 14206
ab2e99db6702
permissions
-rw-r--r--

8062947: Fix exception message to correctly represent LDAP connection failure
Reviewed-by: dfuchs, xyin, vtewari

     1 /*
     2  * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.
     8  *
     9  * This code is distributed in the hope that it will be useful, but WITHOUT
    10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    12  * version 2 for more details (a copy is included in the LICENSE file that
    13  * accompanied this code).
    14  *
    15  * You should have received a copy of the GNU General Public License version
    16  * 2 along with this work; if not, write to the Free Software Foundation,
    17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    18  *
    19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    20  * or visit www.oracle.com if you need additional information or have any
    21  * questions.
    22  */
    24 /*
    25  * @test
    26  * @bug 8062947
    27  * @summary Test that NamingException message text matches the failure reason
    28  * @library lib/
    29  * @library /lib/testlibrary
    30  * @run testng NamingExceptionMessageTest
    31  */
    33 import javax.naming.Context;
    34 import javax.naming.NamingException;
    35 import javax.naming.directory.InitialDirContext;
    36 import java.io.IOException;
    37 import java.io.OutputStream;
    38 import java.net.InetAddress;
    39 import java.net.InetSocketAddress;
    40 import java.net.ServerSocket;
    41 import java.net.Socket;
    42 import java.util.Hashtable;
    43 import java.util.concurrent.CountDownLatch;
    44 import java.util.concurrent.TimeUnit;
    46 import org.testng.annotations.Test;
    47 import org.testng.Assert;
    48 import jdk.testlibrary.net.URIBuilder;
    50 public class NamingExceptionMessageTest {
    52     @Test
    53     public void timeoutMessageTest() throws Exception {
    54         try (TestLdapServer ldapServer = TestLdapServer.newInstance(false)) {
    55             ldapServer.start();
    56             ldapServer.awaitStartup();
    57             Hashtable<Object, Object> env = ldapServer.getInitialLdapCtxEnvironment(TIMEOUT_VALUE);
    58             Exception namingException = Assert.expectThrows(NamingException.class, () -> new InitialDirContext(env));
    59             System.out.println("Got naming exception:" + namingException);
    60             Assert.assertEquals(namingException.getMessage(), EXPECTED_TIMEOUT_MESSAGE);
    61         }
    62     }
    64     @Test
    65     public void connectionClosureMessageTest() throws Exception {
    66         try (TestLdapServer ldapServer = TestLdapServer.newInstance(true)) {
    67             ldapServer.start();
    68             ldapServer.awaitStartup();
    69             Hashtable<Object, Object> env = ldapServer.getInitialLdapCtxEnvironment(0);
    70             Exception namingException = Assert.expectThrows(NamingException.class, () -> new InitialDirContext(env));
    71             System.out.println("Got naming exception:" + namingException);
    72             Assert.assertEquals(namingException.getMessage(), EXPECTED_CLOSURE_MESSAGE);
    73         }
    74     }
    76     // Test LDAP server
    77     private static class TestLdapServer extends BaseLdapServer {
    79         private final boolean closeConnections;
    80         private final CountDownLatch startupLatch = new CountDownLatch(1);
    82         public Hashtable<Object, Object> getInitialLdapCtxEnvironment(int readTimeoutValue) {
    83             // Create environment for initial LDAP context
    84             Hashtable<Object, Object> env = new Hashtable<>();
    86             // Activate LDAPv3
    87             env.put("java.naming.ldap.version", "3");
    89             // De-activate the ManageDsaIT control
    90             env.put(Context.REFERRAL, "follow");
    91             env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
    92             env.put(Context.PROVIDER_URL, getUrlString());
    93             env.put(Context.SECURITY_AUTHENTICATION, "simple");
    94             env.put(Context.SECURITY_PRINCIPAL, "name");
    95             env.put(Context.SECURITY_CREDENTIALS, "pwd");
    97             if (readTimeoutValue > 0) {
    98                 env.put("com.sun.jndi.ldap.read.timeout", String.valueOf(readTimeoutValue));
    99                 env.put("com.sun.jndi.ldap.connect.timeout", String.valueOf(readTimeoutValue));
   100             }
   102             return env;
   103         }
   105         private String getUrlString() {
   106             String url = URIBuilder.newBuilder()
   107                     .scheme("ldap")
   108                     .loopback()
   109                     .port(getPort())
   110                     .buildUnchecked()
   111                     .toString();
   112             return url;
   113         }
   115         public static TestLdapServer newInstance(boolean closeConnections) throws IOException {
   116             ServerSocket srvSock = new ServerSocket();
   117             srvSock.bind(new InetSocketAddress(InetAddress.getLoopbackAddress(), 0));
   118             return new TestLdapServer(srvSock, closeConnections);
   119         }
   121         void awaitStartup() throws InterruptedException {
   122             startupLatch.await();
   123         }
   125         private TestLdapServer(ServerSocket serverSocket, boolean closeConnections) {
   126             super(serverSocket);
   127             this.closeConnections = closeConnections;
   129         }
   131         @Override
   132         protected void beforeAcceptingConnections() {
   133             startupLatch.countDown();
   134         }
   136         @Override
   137         protected void handleRequest(Socket socket,
   138                                      LdapMessage msg,
   139                                      OutputStream out)
   140                 throws IOException {
   141             switch (msg.getOperation()) {
   142                 case BIND_REQUEST:
   143                     if (closeConnections) {
   144                         closeSilently(socket);
   145                     } else {
   146                         try {
   147                             TimeUnit.DAYS.sleep(Integer.MAX_VALUE);
   148                         } catch (InterruptedException e) {
   149                             Thread.currentThread().interrupt();
   150                         }
   151                     }
   152                 default:
   153                     break;
   154             }
   155         }
   156     }
   158     // Expected message for case when connection is closed on server side
   159     private static final String EXPECTED_CLOSURE_MESSAGE = "LDAP connection has been closed";
   160     // read and connect timeouts value
   161     private static final int TIMEOUT_VALUE = 129;
   162     // Expected message text when connection is timed-out
   163     private static final String EXPECTED_TIMEOUT_MESSAGE = String.format(
   164             "LDAP response read timed out, timeout used: %d ms.", TIMEOUT_VALUE);
   165 }

mercurial