test/jdk/com/sun/jndi/ldap/DisconnectNPETest.java
branchJDK-8210696-branch
changeset 57345 ff884a2f247b
parent 51760 caac55d48dc3
equal deleted inserted replaced
57343:9a11a7e1c035 57345:ff884a2f247b
     1 /*
     1 /*
     2  * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
     2  * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     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
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.
     7  * published by the Free Software Foundation.
    23 
    23 
    24 import javax.naming.Context;
    24 import javax.naming.Context;
    25 import javax.naming.NamingException;
    25 import javax.naming.NamingException;
    26 import javax.naming.directory.DirContext;
    26 import javax.naming.directory.DirContext;
    27 import javax.naming.directory.InitialDirContext;
    27 import javax.naming.directory.InitialDirContext;
    28 import java.io.Closeable;
       
    29 import java.io.IOException;
    28 import java.io.IOException;
    30 import java.io.InputStream;
       
    31 import java.io.OutputStream;
       
    32 import java.net.InetAddress;
    29 import java.net.InetAddress;
    33 import java.net.ServerSocket;
    30 import java.net.ServerSocket;
    34 import java.net.Socket;
       
    35 import java.util.Hashtable;
    31 import java.util.Hashtable;
    36 
    32 
    37 /*
    33 /*
    38  * @test
    34  * @test
    39  * @bug 8205330
    35  * @bug 8205330
    40  * @summary Test that If a connection has already been established and then
    36  * @summary Test that If a connection has already been established and then
    41  *          the LDAP directory server sends an (unsolicited)
    37  *          the LDAP directory server sends an (unsolicited)
    42  *          "Notice of Disconnection", make sure client handle it correctly,
    38  *          "Notice of Disconnection", make sure client handle it correctly,
    43  *          no NPE been thrown.
    39  *          no NPE been thrown.
       
    40  * @library lib/
    44  * @run main/othervm DisconnectNPETest
    41  * @run main/othervm DisconnectNPETest
    45  */
    42  */
    46 
    43 
    47 public class DisconnectNPETest {
    44 public class DisconnectNPETest {
    48     // Normally the NPE bug should be hit less than 100 times run, but just in
    45     // Normally the NPE bug should be hit less than 100 times run, but just in
    49     // case, we set repeat count to 1000 here.
    46     // case, we set repeat count to 1000 here.
    50     private static final int REPEAT_COUNT = 1000;
    47     private static final int REPEAT_COUNT = 1000;
    51 
    48 
       
    49     // "Notice of Disconnection" message
       
    50     private static final byte[] DISCONNECT_MSG = { 0x30, 0x4C, 0x02, 0x01, 0x00,
       
    51             0x78, 0x47, 0x0A, 0x01, 0x34, 0x04, 0x00, 0x04, 0x28, 0x55, 0x4E,
       
    52             0x41, 0x56, 0x41, 0x49, 0x4C, 0x41, 0x42, 0x4C, 0x45, 0x3A, 0x20,
       
    53             0x54, 0x68, 0x65, 0x20, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20,
       
    54             0x77, 0x69, 0x6C, 0x6C, 0x20, 0x64, 0x69, 0x73, 0x63, 0x6F, 0x6E,
       
    55             0x6E, 0x65, 0x63, 0x74, 0x21, (byte) 0x8A, 0x16, 0x31, 0x2E, 0x33,
       
    56             0x2E, 0x36, 0x2E, 0x31, 0x2E, 0x34, 0x2E, 0x31, 0x2E, 0x31, 0x34,
       
    57             0x36, 0x36, 0x2E, 0x32, 0x30, 0x30, 0x33, 0x36 };
       
    58     private static final byte[] BIND_RESPONSE = { 0x30, 0x0C, 0x02, 0x01, 0x01,
       
    59             0x61, 0x07, 0x0A, 0x01, 0x00, 0x04, 0x00, 0x04, 0x00 };
       
    60 
    52     public static void main(String[] args) throws IOException {
    61     public static void main(String[] args) throws IOException {
    53         new DisconnectNPETest().run();
    62         new DisconnectNPETest().run();
    54     }
    63     }
    55 
    64 
    56     private ServerSocket serverSocket;
    65     private ServerSocket serverSocket;
    57     private Hashtable<Object, Object> env;
    66     private Hashtable<Object, Object> env;
    58     private TestLDAPServer server;
       
    59 
    67 
    60     private void initRes() throws IOException {
    68     private void initRes() throws IOException {
    61         serverSocket = new ServerSocket(0, 0, InetAddress.getLoopbackAddress());
    69         serverSocket = new ServerSocket(0, 0, InetAddress.getLoopbackAddress());
    62         server = new TestLDAPServer();
       
    63         server.start();
       
    64     }
    70     }
    65 
    71 
    66     private void initTest() {
    72     private void initTest() {
    67         env = new Hashtable<>();
    73         env = new Hashtable<>();
    68         env.put(Context.INITIAL_CONTEXT_FACTORY,
    74         env.put(Context.INITIAL_CONTEXT_FACTORY,
    78 
    84 
    79     private void run() throws IOException {
    85     private void run() throws IOException {
    80         initRes();
    86         initRes();
    81         initTest();
    87         initTest();
    82         int count = 0;
    88         int count = 0;
    83         try {
    89         try (BaseLdapServer ignored = new BaseLdapServer(serverSocket)
       
    90                 .setCommonRequestHandler((msg, out) -> {
       
    91                     if (msg.getOperation()
       
    92                             == LdapMessage.Operation.BIND_REQUEST) {
       
    93                         out.write(BIND_RESPONSE);
       
    94                         out.write(DISCONNECT_MSG);
       
    95                     }
       
    96                 }).startServer()) {
    84             while (count < REPEAT_COUNT) {
    97             while (count < REPEAT_COUNT) {
    85                 count++;
    98                 count++;
    86                 InitialDirContext context = null;
    99                 InitialDirContext context = null;
    87                 try {
   100                 try {
    88                     context = new InitialDirContext(env);
   101                     context = new InitialDirContext(env);
    95                     cleanupContext(context);
   108                     cleanupContext(context);
    96                 }
   109                 }
    97             }
   110             }
    98         } finally {
   111         } finally {
    99             System.out.println("Test count: " + count + "/" + REPEAT_COUNT);
   112             System.out.println("Test count: " + count + "/" + REPEAT_COUNT);
   100             cleanupTest();
       
   101         }
   113         }
   102     }
       
   103 
       
   104     private void cleanupTest() {
       
   105         if (server != null) {
       
   106             server.stopServer();
       
   107         }
       
   108         cleanupClosableRes(serverSocket);
       
   109     }
   114     }
   110 
   115 
   111     private void cleanupContext(DirContext context) {
   116     private void cleanupContext(DirContext context) {
   112         if (context != null) {
   117         if (context != null) {
   113             try {
   118             try {
   115             } catch (NamingException e) {
   120             } catch (NamingException e) {
   116                 // ignore
   121                 // ignore
   117             }
   122             }
   118         }
   123         }
   119     }
   124     }
   120 
       
   121     private static void cleanupClosableRes(Closeable res) {
       
   122         if (res != null) {
       
   123             try {
       
   124                 res.close();
       
   125             } catch (Exception e) {
       
   126                 // ignore
       
   127             }
       
   128         }
       
   129     }
       
   130 
       
   131     class TestLDAPServer extends Thread {
       
   132         private volatile boolean isRunning;
       
   133 
       
   134         TestLDAPServer() {
       
   135             isRunning = true;
       
   136         }
       
   137 
       
   138         private void stopServer() {
       
   139             isRunning = false;
       
   140         }
       
   141 
       
   142         @Override
       
   143         public void run() {
       
   144             try {
       
   145                 while (isRunning) {
       
   146                     Socket clientSocket = serverSocket.accept();
       
   147                     Thread handler = new Thread(
       
   148                             new LDAPServerHandler(clientSocket));
       
   149                     handler.start();
       
   150                 }
       
   151             } catch (IOException e) {
       
   152                 if (isRunning) {
       
   153                     throw new RuntimeException(e);
       
   154                 }
       
   155             }
       
   156         }
       
   157     }
       
   158 
       
   159     static class LDAPServerHandler implements Runnable {
       
   160         // "Notice of Disconnection" message
       
   161         private static final byte[] DISCONNECT_MSG = { 0x30, 0x4C, 0x02, 0x01,
       
   162                 0x00, 0x78, 0x47, 0x0A, 0x01, 0x34, 0x04, 0x00, 0x04, 0x28,
       
   163                 0x55, 0x4E, 0x41, 0x56, 0x41, 0x49, 0x4C, 0x41, 0x42, 0x4C,
       
   164                 0x45, 0x3A, 0x20, 0x54, 0x68, 0x65, 0x20, 0x73, 0x65, 0x72,
       
   165                 0x76, 0x65, 0x72, 0x20, 0x77, 0x69, 0x6C, 0x6C, 0x20, 0x64,
       
   166                 0x69, 0x73, 0x63, 0x6F, 0x6E, 0x6E, 0x65, 0x63, 0x74, 0x21,
       
   167                 (byte) 0x8A, 0x16, 0x31, 0x2E, 0x33, 0x2E, 0x36, 0x2E, 0x31,
       
   168                 0x2E, 0x34, 0x2E, 0x31, 0x2E, 0x31, 0x34, 0x36, 0x36, 0x2E,
       
   169                 0x32, 0x30, 0x30, 0x33, 0x36 };
       
   170         private static final byte[] BIND_RESPONSE = { 0x30, 0x0C, 0x02, 0x01,
       
   171                 0x01, 0x61, 0x07, 0x0A, 0x01, 0x00, 0x04, 0x00, 0x04, 0x00 };
       
   172         private final Socket clientSocket;
       
   173 
       
   174         private LDAPServerHandler(final Socket clientSocket) {
       
   175             this.clientSocket = clientSocket;
       
   176         }
       
   177 
       
   178         @Override
       
   179         public void run() {
       
   180             try (clientSocket;
       
   181                     OutputStream out = clientSocket.getOutputStream();
       
   182                     InputStream in = clientSocket.getInputStream()) {
       
   183                 if (in.read() > 0) {
       
   184                     in.skip(in.available());
       
   185                     out.write(BIND_RESPONSE);
       
   186                     out.write(DISCONNECT_MSG);
       
   187                 }
       
   188             } catch (IOException e) {
       
   189                 e.printStackTrace();
       
   190             }
       
   191         }
       
   192     }
       
   193 }
   125 }