1 import java.net.Socket; 2 import java.net.ServerSocket; 3 import java.io.*; 4 import javax.naming.*; 5 import javax.naming.directory.*; 6 import java.util.Hashtable; 7 import java.util.concurrent.*; 8 9 /** 10 * @test 11 * @compile TestDnsProvider.java 12 * @run main/othervm LdapDnsProviderTest 13 * @modules java.naming/com.sun.jndi.ldap 14 * @bug 8160768 15 * @summary ctx provider tests for ldap 16 */ 17 18 class ProviderTest implements Callable { 19 20 private final String expected; 21 private final ScheduledExecutorService killSwitchPool; 22 private final LdapTestServer server; 23 private final Hashtable env = new Hashtable(11); 24 private final int HANGING_TEST_TIMEOUT = 1000; 25 26 public ProviderTest(LdapTestServer server, 27 ScheduledExecutorService killSwitchPool, 28 String expected, 29 String dnsProvider) 30 throws IOException 31 { 32 this.server = server; 33 this.killSwitchPool = killSwitchPool; 34 this.expected = expected; 35 env.put("com.sun.jndi.ldap.dnsProvider", dnsProvider); 36 env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory"); 37 } 38 39 boolean shutItDown(InitialContext ctx) { 40 try { 41 if (ctx != null) ctx.close(); 42 return true; 43 } catch (NamingException ex) { 44 return false; 45 } 46 } 47 48 public Boolean call() { 49 boolean passed; 50 InitialContext ctx = null; 51 ScheduledFuture killer = null; 52 // String providerUrl = "ldap://localhost:" + server.getLocalPort(); 53 String providerUrl = "ldap:///dc=example,dc=com"; 54 55 try { 56 while(!server.accepting()) { 57 Thread.sleep(200); // allow the server to start up 58 } 59 Thread.sleep(200); // to be sure 60 61 // if this is a hanging test, scheduled a thread to 62 // interrupt after a certain time 63 if (killSwitchPool != null) { 64 final Thread current = Thread.currentThread(); 65 killer = killSwitchPool.schedule( 66 new Callable<Void>() { 67 public Void call() throws Exception { 68 current.interrupt(); 69 return null; 70 } 71 }, HANGING_TEST_TIMEOUT, TimeUnit.MILLISECONDS); 72 } 73 74 env.put(Context.PROVIDER_URL, providerUrl); 75 76 try { 77 ctx = new InitialDirContext(env); 78 SearchControls scl = new SearchControls(); 79 scl.setSearchScope(SearchControls.SUBTREE_SCOPE); 80 NamingEnumeration<SearchResult> answer = ((InitialDirContext)ctx) 81 .search("ou=People,o=Test", "(objectClass=*)", scl); 82 throw new RuntimeException("Search should not complete"); 83 } catch (NamingException e) { 84 passed = e.toString().indexOf(expected) > -1; 85 } finally { 86 if (killer != null && !killer.isDone()) { 87 killer.cancel(true); 88 } 89 shutItDown(ctx); 90 server.close(); 91 } 92 return passed; 93 } catch (IOException|InterruptedException e) { 94 throw new RuntimeException(e); 95 } 96 } 97 } 98 99 100 class LdapTestServer extends Thread { 101 ServerSocket serverSock; 102 boolean accepting = false; 103 private byte[] bindResponse = { 104 0x30, 0x0C, 0x02, 0x01, 0x01, 0x61, 0x07, 0x0A, 105 0x01, 0x00, 0x04, 0x00, 0x04, 0x00 106 }; 107 108 public LdapTestServer() throws IOException { 109 this.serverSock = new ServerSocket(0); 110 start(); 111 } 112 113 public int getLocalPort() { 114 return serverSock.getLocalPort(); 115 } 116 117 public boolean accepting() { 118 return accepting; 119 } 120 121 public void close() throws IOException { 122 serverSock.close(); 123 } 124 125 public void run() { 126 try { 127 accepting = true; 128 Socket socket = serverSock.accept(); 129 InputStream in = socket.getInputStream(); 130 OutputStream out = socket.getOutputStream(); 131 132 // Read the LDAP BindRequest 133 while (in.read() != -1) { 134 in.skip(in.available()); 135 break; 136 } 137 138 // Write an LDAP BindResponse 139 out.write(bindResponse); 140 out.flush(); 141 } catch (IOException e) { 142 // ignore 143 } 144 } 145 } 146 147 public class LdapDnsProviderTest { 148 149 private static final ExecutorService testPool = 150 Executors.newFixedThreadPool(1); 151 private static final ScheduledExecutorService killSwitchPool = 152 Executors.newScheduledThreadPool(1); 153 154 public static void main(String[] args) throws Exception { 155 LdapTestServer server = new LdapTestServer(); 156 try { 157 runTest(server, "yupyupyup:389", TestDnsProvider.class.getName()); 158 runTest(server, "localhost:389", 159 com.sun.jndi.ldap.DefaultLdapDnsProvider.class.getName()); 160 } finally { 161 LdapDnsProviderTest.killSwitchPool.shutdown(); 162 LdapDnsProviderTest.testPool.shutdown(); 163 } 164 } 165 166 private static boolean runTest(LdapTestServer server, 167 String expected, 168 String dnsProvider) 169 throws IOException, InterruptedException, ExecutionException 170 { 171 Future test = testPool.submit( 172 new ProviderTest( 173 server, killSwitchPool, expected, dnsProvider)); 174 175 while (!test.isDone()) { 176 if ((Boolean) test.get()) { 177 return true; 178 } 179 } 180 throw new AssertionError("FAILED: " + expected + ", " + dnsProvider); 181 } 182 183 } 184