From dc896cae01b3939c64ecade9ed7dd642b379d528 Mon Sep 17 00:00:00 2001
From: Matthew Swift <matthew.swift@forgerock.com>
Date: Mon, 30 Sep 2013 16:10:06 +0000
Subject: [PATCH] Backport unit test for OPENDJ-1156: NPE in ReferenceCountedObject after shutting down directory

---
 opendj-ldap-sdk/src/test/java/org/forgerock/opendj/ldap/MockConnectionEventListener.java   |    4 +
 opendj-ldap-sdk/src/test/java/org/forgerock/opendj/ldap/LDAPConnectionFactoryTestCase.java |   97 ++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 100 insertions(+), 1 deletions(-)

diff --git a/opendj-ldap-sdk/src/test/java/org/forgerock/opendj/ldap/LDAPConnectionFactoryTestCase.java b/opendj-ldap-sdk/src/test/java/org/forgerock/opendj/ldap/LDAPConnectionFactoryTestCase.java
new file mode 100644
index 0000000..01c2914
--- /dev/null
+++ b/opendj-ldap-sdk/src/test/java/org/forgerock/opendj/ldap/LDAPConnectionFactoryTestCase.java
@@ -0,0 +1,97 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License").  You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at legal-notices/CDDLv1_0.txt
+ * or http://forgerock.org/license/CDDLv1.0.html.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at legal-notices/CDDLv1_0.txt.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information:
+ *      Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ *
+ *
+ *     Copyright 2013 ForgeRock AS.
+ */
+package org.forgerock.opendj.ldap;
+
+import static org.fest.assertions.Assertions.assertThat;
+import static org.forgerock.opendj.ldap.TestCaseUtils.findFreeSocketAddress;
+import static org.mockito.Mockito.mock;
+
+import java.io.IOException;
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicReference;
+
+import org.testng.annotations.Test;
+
+/**
+ * Tests the {@link LDAPConnectionFactory} class.
+ */
+@SuppressWarnings("javadoc")
+public class LDAPConnectionFactoryTestCase extends SdkTestCase {
+    // Test timeout for tests which need to wait for network events.
+    private static final long TEST_TIMEOUT = 30L;
+
+    /**
+     * This unit test exposes the bug raised in issue OPENDJ-1156: NPE in
+     * ReferenceCountedObject after shutting down directory.
+     */
+    @Test
+    public void testResourceManagement() throws Exception {
+        final AtomicReference<LDAPClientContext> context = new AtomicReference<LDAPClientContext>();
+        final Semaphore latch = new Semaphore(0);
+        final LDAPListener server = createServer(latch, context);
+        final ConnectionFactory factory = new LDAPConnectionFactory(server.getSocketAddress());
+        try {
+            for (int i = 0; i < 100; i++) {
+                // Connect to the server.
+                final Connection connection = factory.getConnection();
+                try {
+                    // Wait for the server to accept the connection.
+                    assertThat(latch.tryAcquire(TEST_TIMEOUT, TimeUnit.SECONDS)).isTrue();
+
+                    final MockConnectionEventListener listener = new MockConnectionEventListener();
+                    connection.addConnectionEventListener(listener);
+
+                    // Perform remote disconnect which will trigger a client side connection error.
+                    context.get().disconnect();
+
+                    // Wait for the error notification to reach the client.
+                    listener.awaitError(TEST_TIMEOUT, TimeUnit.SECONDS);
+                } finally {
+                    connection.close();
+                }
+            }
+        } finally {
+            factory.close();
+            server.close();
+        }
+    }
+
+    private LDAPListener createServer(final Semaphore latch,
+            final AtomicReference<LDAPClientContext> context) throws IOException {
+        return new LDAPListener(findFreeSocketAddress(),
+                new ServerConnectionFactory<LDAPClientContext, Integer>() {
+                    @SuppressWarnings("unchecked")
+                    @Override
+                    public ServerConnection<Integer> handleAccept(
+                            final LDAPClientContext clientContext) throws ErrorResultException {
+                        context.set(clientContext);
+                        latch.release();
+                        return mock(ServerConnection.class);
+                    }
+                });
+    }
+}
diff --git a/opendj-ldap-sdk/src/test/java/org/forgerock/opendj/ldap/MockConnectionEventListener.java b/opendj-ldap-sdk/src/test/java/org/forgerock/opendj/ldap/MockConnectionEventListener.java
index 16e56a0..c31c0dc 100644
--- a/opendj-ldap-sdk/src/test/java/org/forgerock/opendj/ldap/MockConnectionEventListener.java
+++ b/opendj-ldap-sdk/src/test/java/org/forgerock/opendj/ldap/MockConnectionEventListener.java
@@ -25,6 +25,8 @@
  */
 package org.forgerock.opendj.ldap;
 
+import static org.fest.assertions.Assertions.assertThat;
+
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicInteger;
@@ -100,7 +102,7 @@
 
     private void await(CountDownLatch latch, long timeout, TimeUnit unit) {
         try {
-            latch.await(timeout, unit);
+            assertThat(latch.await(timeout, unit)).isTrue();
         } catch (InterruptedException e) {
             Thread.currentThread().interrupt();
         }

--
Gitblit v1.10.0