You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by se...@apache.org on 2015/04/26 20:53:08 UTC

svn commit: r1676138 - /directory/apacheds/trunk/ldap-client-test/src/test/java/org/apache/directory/shared/client/api/operations/ConcurrentSearchAndUnbindTest.java

Author: seelmann
Date: Sun Apr 26 18:53:08 2015
New Revision: 1676138

URL: http://svn.apache.org/r1676138
Log:
Another test to demonstrate DIRAPI-236

Added:
    directory/apacheds/trunk/ldap-client-test/src/test/java/org/apache/directory/shared/client/api/operations/ConcurrentSearchAndUnbindTest.java

Added: directory/apacheds/trunk/ldap-client-test/src/test/java/org/apache/directory/shared/client/api/operations/ConcurrentSearchAndUnbindTest.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/ldap-client-test/src/test/java/org/apache/directory/shared/client/api/operations/ConcurrentSearchAndUnbindTest.java?rev=1676138&view=auto
==============================================================================
--- directory/apacheds/trunk/ldap-client-test/src/test/java/org/apache/directory/shared/client/api/operations/ConcurrentSearchAndUnbindTest.java (added)
+++ directory/apacheds/trunk/ldap-client-test/src/test/java/org/apache/directory/shared/client/api/operations/ConcurrentSearchAndUnbindTest.java Sun Apr 26 18:53:08 2015
@@ -0,0 +1,160 @@
+/*
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *   or more contributor license agreements.  See the NOTICE file
+ *   distributed with this work for additional information
+ *   regarding copyright ownership.  The ASF licenses this file
+ *   to you under the Apache License, Version 2.0 (the
+ *   "License"); you may not use this file except in compliance
+ *   with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing,
+ *   software distributed under the License is distributed on an
+ *   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *   KIND, either express or implied.  See the License for the
+ *   specific language governing permissions and limitations
+ *   under the License.
+ *
+ */
+
+package org.apache.directory.shared.client.api.operations;
+
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicLong;
+
+import org.apache.directory.api.ldap.model.cursor.EntryCursor;
+import org.apache.directory.api.ldap.model.message.SearchScope;
+import org.apache.directory.api.ldap.model.name.Dn;
+import org.apache.directory.ldap.client.api.LdapConnection;
+import org.apache.directory.ldap.client.api.LdapNetworkConnection;
+import org.apache.directory.server.annotations.CreateLdapServer;
+import org.apache.directory.server.annotations.CreateTransport;
+import org.apache.directory.server.core.integ.AbstractLdapTestUnit;
+import org.apache.directory.server.core.integ.FrameworkRunner;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+
+/**
+ * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
+ */
+@RunWith(FrameworkRunner.class)
+@CreateLdapServer(transports =
+    { @CreateTransport(protocol = "LDAP"), @CreateTransport(protocol = "LDAPS") })
+public class ConcurrentSearchAndUnbindTest extends AbstractLdapTestUnit
+{
+
+    private static final int NUM_ROUNDS = 50;
+
+
+    /**
+     * DIRAPI-236
+     */
+    @Test
+    @Ignore
+    public void testConcurrentSearchAndUnbind() throws Exception
+    {
+        final LdapConnection connection = new LdapNetworkConnection( "localhost", getLdapServer().getPort() );
+
+        ExecutorService pool = Executors.newFixedThreadPool( 2 );
+
+        final AtomicLong unbindCount = new AtomicLong();
+        final AtomicLong bindCount = new AtomicLong();
+        final AtomicLong searchCount = new AtomicLong();
+        final AtomicLong resultCount = new AtomicLong();
+
+        // Thread that permanently unbinds the connection
+        Callable<Void> unbindCallable = new Callable<Void>()
+        {
+            @Override
+            public Void call() throws Exception
+            {
+                while ( true )
+                {
+                    try
+                    {
+                        System.out.println( "unbind thread: unbind" );
+                        unbindCount.incrementAndGet();
+                        connection.unBind();
+                        //connection.close();
+                    }
+                    catch ( Exception e )
+                    {
+                        // expected when other thread didn't bind
+                        //System.out.println( "unbind thread: " + e.getMessage() );
+                    }
+                    Thread.sleep( 1000 );
+                }
+            }
+        };
+        Future<Void> unbindFuture = pool.submit( unbindCallable );
+
+        // Thread that permanently uses the connection, until the other thread unbinds
+        Callable<Void> bindAndSearchCallable = new Callable<Void>()
+        {
+            @Override
+            public Void call()
+            {
+                for ( int i = 0; i < NUM_ROUNDS; i++ )
+                {
+                    System.out.println( "search thread: round " + i );
+                    try
+                    {
+                        bindCount.incrementAndGet();
+                        connection.bind( "uid=admin,ou=system", "secret" );
+
+                        while ( true )
+                        {
+                            searchCount.incrementAndGet();
+                            EntryCursor cursor = connection.search( new Dn( "ou=system" ), "(objectClass=*)",
+                                SearchScope.SUBTREE, "*" );
+                            while ( cursor.next() )
+                            {
+                                resultCount.incrementAndGet();
+                                cursor.get();
+                            }
+                            cursor.close();
+                        }
+                    }
+                    catch ( Throwable e )
+                    {
+                        // expected when other thread unbinds
+                        //System.out.println( "search thread: " + e.getMessage() );
+                    }
+                }
+                return null;
+            }
+        };
+        Future<Void> bindAndSearchFuture = pool.submit( bindAndSearchCallable );
+
+        // wait till bindAndSearchFuture is done
+        bindAndSearchFuture.get( 600, TimeUnit.SECONDS );
+
+        // assert counters
+        System.out.println( "unbindCount: " + unbindCount );
+        System.out.println( "bindCount: " + bindCount );
+        System.out.println( "searchCount: " + searchCount );
+        System.out.println( "resultCount: " + resultCount );
+        assertTrue( unbindCount.get() >= NUM_ROUNDS );
+        assertEquals( NUM_ROUNDS, bindCount.get() );
+        assertTrue( searchCount.get() > 0 );
+        assertTrue( resultCount.get() > 0 );
+
+        // cleanup
+        pool.shutdownNow();
+        pool.awaitTermination( 60, TimeUnit.SECONDS );
+        assertTrue( unbindFuture.isDone() );
+        assertTrue( bindAndSearchFuture.isDone() );
+        connection.close();
+    }
+}