You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by ma...@apache.org on 2007/07/22 01:47:37 UTC

svn commit: r558395 - in /directory/apacheds/trunk/mitosis/src: main/java/org/apache/directory/mitosis/service/ test/java/org/apache/directory/mitosis/service/

Author: malderson
Date: Sat Jul 21 16:47:36 2007
New Revision: 558395

URL: http://svn.apache.org/viewvc?view=rev&rev=558395
Log:
Made the replication service integration test more correct, more reliable and more controlled.  We should now be less dependent on timing.

Modified:
    directory/apacheds/trunk/mitosis/src/main/java/org/apache/directory/mitosis/service/ClientConnectionManager.java
    directory/apacheds/trunk/mitosis/src/main/java/org/apache/directory/mitosis/service/ReplicationService.java
    directory/apacheds/trunk/mitosis/src/test/java/org/apache/directory/mitosis/service/ReplicationServiceITest.java

Modified: directory/apacheds/trunk/mitosis/src/main/java/org/apache/directory/mitosis/service/ClientConnectionManager.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/mitosis/src/main/java/org/apache/directory/mitosis/service/ClientConnectionManager.java?view=diff&rev=558395&r1=558394&r2=558395
==============================================================================
--- directory/apacheds/trunk/mitosis/src/main/java/org/apache/directory/mitosis/service/ClientConnectionManager.java (original)
+++ directory/apacheds/trunk/mitosis/src/main/java/org/apache/directory/mitosis/service/ClientConnectionManager.java Sat Jul 21 16:47:36 2007
@@ -136,6 +136,27 @@
             }
         }
     }
+    
+    /**
+     * Interrupt the unconnected connections to make them attempt to connect immediately.
+     *
+     */
+    public void interruptConnectors()
+    {
+        for( Iterator i = sessions.values().iterator(); i.hasNext(); )
+        {
+            Connection con = ( Connection ) i.next();
+            synchronized( con )
+            {
+                // Wake up the replicas that are sleeping.
+                if ( con.inProgress && con.connector != null )
+                {
+                    con.connector.interrupt();
+                }
+            }
+        }
+        
+    }
 
     private class ConnectionMonitor extends Thread
     {

Modified: directory/apacheds/trunk/mitosis/src/main/java/org/apache/directory/mitosis/service/ReplicationService.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/mitosis/src/main/java/org/apache/directory/mitosis/service/ReplicationService.java?view=diff&rev=558395&r1=558394&r2=558395
==============================================================================
--- directory/apacheds/trunk/mitosis/src/main/java/org/apache/directory/mitosis/service/ReplicationService.java (original)
+++ directory/apacheds/trunk/mitosis/src/main/java/org/apache/directory/mitosis/service/ReplicationService.java Sat Jul 21 16:47:36 2007
@@ -265,6 +265,15 @@
         this.clientConnectionManager.replicate();
     }
 
+    /**
+     * Wake the sleeping (unconnected) replicas.
+     */
+    public void interruptConnectors()
+    {
+        log.info( "Waking sleeping replicas..." );
+        this.clientConnectionManager.interruptConnectors();
+    }
+
 
     /**
      * Purges old replication logs and the old entries marked as 'deleted'

Modified: directory/apacheds/trunk/mitosis/src/test/java/org/apache/directory/mitosis/service/ReplicationServiceITest.java
URL: http://svn.apache.org/viewvc/directory/apacheds/trunk/mitosis/src/test/java/org/apache/directory/mitosis/service/ReplicationServiceITest.java?view=diff&rev=558395&r1=558394&r2=558395
==============================================================================
--- directory/apacheds/trunk/mitosis/src/test/java/org/apache/directory/mitosis/service/ReplicationServiceITest.java (original)
+++ directory/apacheds/trunk/mitosis/src/test/java/org/apache/directory/mitosis/service/ReplicationServiceITest.java Sat Jul 21 16:47:36 2007
@@ -61,8 +61,8 @@
  */
 public class ReplicationServiceITest extends TestCase
 {
-    private Map contexts = new HashMap();
-    private Map replicationServices = new HashMap();
+    private Map<String, LdapContext> contexts = new HashMap<String, LdapContext>();
+    private Map<String, ReplicationService> replicationServices = new HashMap<String, ReplicationService>();
 
     protected void setUp() throws Exception
     {
@@ -76,12 +76,20 @@
 
     public void testOneWay() throws Exception
     {
-        String dn1 = "cn=test,ou=system";
-        testOneWayBind( dn1 );
-        testOneWayUnbind( dn1 );
+        String dn = "cn=test,ou=system";
+        testOneWayBind( dn );
+        testOneWayUnbind( dn );
     }
     
-    public void _testTwoWayBind() throws Exception
+    /**
+     * Test that the entry created last will win in the case of a conflict.
+     * 
+     * NOTE: This test is DISABLED as there is an occasional problem when a message is acknowledged
+     * too quickly, meaning no further messages can be sent until it has timed out (DIRSERVER-998).
+     *
+     * @throws Exception
+     */
+    public void disabled_testTwoWayBind() throws Exception
     {
         LdapContext ctxA = getReplicaContext( "A" );
         LdapContext ctxB = getReplicaContext( "B" );
@@ -90,16 +98,27 @@
         Attributes entryA = new AttributesImpl( true );
         entryA.put( "cn", "test" );
         entryA.put( "ou", "A" );
-        entryA.put( "objectClass", "top" );
-        ctxA.bind( "cn=test,ou=system", entryA );
+        entryA.put( "objectClass", "top" ).add( "extensibleObject" );
+        ctxA.bind( "cn=test,ou=system", null, entryA );
+        
+        // Ensure the second bind is undebatebly the second.
+        Thread.sleep( 100 );
 
         Attributes entryB = new AttributesImpl( true );
         entryB.put( "cn", "test" );
         entryB.put( "ou", "B" );
-        entryB.put( "objectClass", "top" );
-        ctxB.bind( "cn=test,ou=system", entryB );
+        entryB.put( "objectClass", "top" ).add( "extensibleObject" );
+        ctxB.bind( "cn=test,ou=system", null, entryB );
 
-        Thread.sleep( 7000 );
+        // Let both replicas replicate.  Note that a replica can only receive
+        // logs from one peer at a time so we must delay between replications.
+        replicationServices.get( "A" ).replicate();
+        
+        Thread.sleep( 5000 );
+        
+        replicationServices.get( "B" ).replicate();
+        
+        Thread.sleep( 5000 );
 
         Assert.assertEquals( "B", getAttributeValue( ctxA, "cn=test,ou=system", "ou" ) );
         Assert.assertEquals( "B", getAttributeValue( ctxB, "cn=test,ou=system", "ou" ) );
@@ -114,11 +133,14 @@
         
         Attributes entry = new AttributesImpl( true );
         entry.put( "cn", "test" );
-        entry.put( "objectClass", "top" );
-        ctxA.bind( dn, entry );
+        entry.put( "objectClass", "top" ).add( "extensibleObject" );
+        ctxA.bind( dn, null, entry );
 
-        Thread.sleep( 7000 );
+        replicationServices.get( "A" ).replicate();
+        
+        Thread.sleep( 5000 );
 
+        Assert.assertNotNull( ctxA.lookup( dn ) );
         Assert.assertNotNull( ctxB.lookup( dn ) );
         Assert.assertNotNull( ctxC.lookup( dn ) );
     }
@@ -131,7 +153,9 @@
         
         ctxA.unbind( dn );
         
-        Thread.sleep( 7000 );
+        replicationServices.get( "A" ).replicate();
+
+        Thread.sleep( 5000 );
         
         assertNotExists( ctxA, dn );
         assertNotExists( ctxB, dn );
@@ -154,7 +178,7 @@
     
     private String getAttributeValue( LdapContext ctx, String name, String attrName ) throws Exception
     {
-        Attribute attr = ( ( Attributes ) ctx.lookup( name ) ).get( attrName );
+        Attribute attr = ctx.getAttributes( name ).get( attrName );
         return ( String ) attr.get();
     }
 
@@ -197,7 +221,7 @@
             ReplicationConfiguration replicationCfg = new ReplicationConfiguration();
             replicationCfg.setReplicaId( replica.getId() );
             // Disable automatic replication to prevent unexpected behavior
-            replicationCfg.setReplicationInterval(1);
+            replicationCfg.setReplicationInterval(0);
             replicationCfg.setServerPort( replica.getAddress().getPort() );
             for( int j = 0; j < replicas.length; j++ )
             {
@@ -207,11 +231,10 @@
                 }
             }
 
-            ReplicationService replicationService = new ReplicationService();
             MutableReplicationInterceptorConfiguration interceptorCfg = 
                 new MutableReplicationInterceptorConfiguration();
             interceptorCfg.setName( "mitosis" );
-            interceptorCfg.setInterceptorClassName( replicationService.getClass().getName() );
+            interceptorCfg.setInterceptorClassName( ReplicationService.class.getName() );
             interceptorCfg.setReplicationConfiguration( replicationCfg );
             interceptorCfgs.add( interceptorCfg );
 
@@ -233,27 +256,35 @@
             // Initialize the server instance.
             LdapContext context = new InitialLdapContext( env, null );
             contexts.put( replicaId, context );
+            ReplicationService replicationService = (ReplicationService) DirectoryService.getInstance( replicaId ).getConfiguration().getInterceptorChain().get( "mitosis" );
             replicationServices.put( replicaId, replicationService );
         }
+
+        // Ensure all replicas have had a chance to connect to each other since the last one started.
+        for( Iterator<ReplicationService> i = replicationServices.values().iterator(); i.hasNext(); )
+        {
+            i.next().interruptConnectors();
+        }
+        Thread.sleep( 1000 );
     }
 
     private LdapContext getReplicaContext( String name ) throws Exception
     {
-        LdapContext context = ( LdapContext ) contexts.get( name );
+        LdapContext context = contexts.get( name );
         if( context == null )
         {
             throw new IllegalArgumentException( "No such replica: " + name );
         }
 
-        return context;
+        return ( LdapContext ) context.lookup( "" );
     }
     
     @SuppressWarnings("unchecked")
     private void destroyAllReplicas() throws Exception
     {
-        for( Iterator i = contexts.keySet().iterator(); i.hasNext(); )
+        for( Iterator<String> i = contexts.keySet().iterator(); i.hasNext(); )
         {
-            String replicaId = ( String ) i.next();
+            String replicaId = i.next();
             File workDir = DirectoryService.getInstance( replicaId )
                     .getConfiguration().getStartupConfiguration()
                     .getWorkingDirectory();