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();
+ }
+}