From 5bac637fff2ddff2d164e49e4a4bdcdd45efb400 Mon Sep 17 00:00:00 2001
From: Jean-Noel Rouvignac <jean-noel.rouvignac@forgerock.com>
Date: Mon, 12 Aug 2013 10:16:57 +0000
Subject: [PATCH] ExternalChangeLogTest.java: Removed another 200 lines. Extracted several methods: newSet(), generateChangeNumbers(), checkDn(), assertDnEquals(), debugAndWriteEntries(), createDomain(), runDeleteOperation(), assertOnlyDoneMsgReceived. Removed useless / unused / plain wrong code. Removed commented out code. assertTrue() => assertEquals(). Used assertj assertThat().

---
 opends/tests/unit-tests-testng/src/server/org/opends/server/replication/ExternalChangeLogTest.java | 1091 +++++++++++++++++++++++----------------------------------
 1 files changed, 438 insertions(+), 653 deletions(-)

diff --git a/opends/tests/unit-tests-testng/src/server/org/opends/server/replication/ExternalChangeLogTest.java b/opends/tests/unit-tests-testng/src/server/org/opends/server/replication/ExternalChangeLogTest.java
index 22e7e2b..b6a3be5 100644
--- a/opends/tests/unit-tests-testng/src/server/org/opends/server/replication/ExternalChangeLogTest.java
+++ b/opends/tests/unit-tests-testng/src/server/org/opends/server/replication/ExternalChangeLogTest.java
@@ -27,14 +27,6 @@
  */
 package org.opends.server.replication;
 
-import static org.opends.messages.ReplicationMessages.*;
-import static org.opends.server.TestCaseUtils.*;
-import static org.opends.server.loggers.debug.DebugLogger.*;
-import static org.opends.server.replication.protocol.OperationContext.*;
-import static org.opends.server.types.ResultCode.*;
-import static org.opends.server.util.StaticUtils.*;
-import static org.testng.Assert.*;
-
 import java.io.*;
 import java.net.Socket;
 import java.util.*;
@@ -69,7 +61,10 @@
 import org.opends.server.tools.LDAPSearch;
 import org.opends.server.tools.LDAPWriter;
 import org.opends.server.types.*;
-import org.opends.server.util.*;
+import org.opends.server.util.LDIFWriter;
+import org.opends.server.util.ServerConstants;
+import org.opends.server.util.StaticUtils;
+import org.opends.server.util.TimeThread;
 import org.opends.server.workflowelement.externalchangelog.ECLSearchOperation;
 import org.opends.server.workflowelement.externalchangelog.ECLWorkflowElement;
 import org.opends.server.workflowelement.localbackend.LocalBackendModifyDNOperation;
@@ -78,6 +73,15 @@
 import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
+import static org.assertj.core.api.Assertions.*;
+import static org.opends.messages.ReplicationMessages.*;
+import static org.opends.server.TestCaseUtils.*;
+import static org.opends.server.loggers.debug.DebugLogger.*;
+import static org.opends.server.replication.protocol.OperationContext.*;
+import static org.opends.server.types.ResultCode.*;
+import static org.opends.server.util.StaticUtils.*;
+import static org.testng.Assert.*;
+
 /**
  * Tests for the replicationServer code.
  */
@@ -114,8 +118,7 @@
    * When used in a search operation, it includes all attributes (user and
    * operational)
    */
-  private final Set<String> ALL_ATTRIBUTES = new LinkedHashSet<String>(Arrays
-      .asList("+", "*"));
+  private final Set<String> ALL_ATTRIBUTES = newSet("+", "*");
 
   /**
    * Set up the environment for performing the tests in this Class.
@@ -412,80 +415,53 @@
     String tn = "ECLRemoteEmpty";
     debugInfo(tn, "Starting test\n\n");
 
-    ReplicationBroker server1 = null;
-    ReplicationBroker server2 = null;
-    ReplicationBroker server3 = null;
+    ReplicationBroker[] brokers = new ReplicationBroker[3];
 
     try
     {
       // Create 3 ECL broker
-      server1 = openReplicationSession(
+      brokers[0] = openReplicationSession(
           DN.decode("cn=changelog"), 1111,
           100, replicationServerPort, brokerSessionTimeout, false);
-      assertTrue(server1.isConnected());
-      server2 = openReplicationSession(
+      assertTrue(brokers[0].isConnected());
+      brokers[1] = openReplicationSession(
           DN.decode("cn=changelog"), 2222,
           100, replicationServerPort,brokerSessionTimeout, false);
-      assertTrue(server2.isConnected());
-      server3 = openReplicationSession(
+      assertTrue(brokers[1].isConnected());
+      brokers[2] = openReplicationSession(
           DN.decode("cn=changelog"), 3333,
           100, replicationServerPort,brokerSessionTimeout, false);
-      assertTrue(server3.isConnected());
+      assertTrue(brokers[2].isConnected());
 
-      // Test broker1 receives only Done
-      ReplicationMsg msg;
-      int msgc=0;
-      do
-      {
-        msg = server1.receive();
-        msgc++;
-      }
-      while(!(msg instanceof DoneMsg));
-      assertTrue(msgc==1,
-          "Ending " + tn + " with incorrect message number :" +
-          msg.getClass().getCanonicalName());
-      assertTrue(msg instanceof DoneMsg,
-      "Ending " + tn + " with incorrect message type :" +
-      msg.getClass().getCanonicalName());
-
-      // Test broker2 receives only Done
-      msgc=0;
-      do
-      {
-        msg = server2.receive();
-        msgc++;
-      }
-      while(!(msg instanceof DoneMsg));
-      assertTrue(msgc==1,
-          "Ending " + tn + " with incorrect message number :" +
-          msg.getClass().getCanonicalName());
-      assertTrue(msg instanceof DoneMsg,
-      "Ending " + tn + " with incorrect message type :" +
-      msg.getClass().getCanonicalName());
-
-      // Test broker3 receives only Done
-      msgc=0;
-      do
-      {
-        msg = server3.receive();
-        msgc++;
-      }
-      while(!(msg instanceof DoneMsg));
-      assertTrue(msgc==1,
-          "Ending " + tn + " with incorrect message number :" +
-          msg.getClass().getCanonicalName());
-      assertTrue(msg instanceof DoneMsg,
-      "Ending " + tn + " with incorrect message type :" +
-      msg.getClass().getCanonicalName());
+      assertOnlyDoneMsgReceived(tn, brokers[0]);
+      assertOnlyDoneMsgReceived(tn, brokers[1]);
+      assertOnlyDoneMsgReceived(tn, brokers[2]);
       debugInfo(tn, "Ending test successfully\n\n");
     }
     finally
     {
-      stop(server2, server3, server1);
+      stop(brokers);
       replicationServer.clearDb();
     }
   }
 
+  private void assertOnlyDoneMsgReceived(String tn, ReplicationBroker server)
+      throws Exception
+  {
+    ReplicationMsg msg;
+    int msgc = 0;
+    do
+    {
+      msg = server.receive();
+      msgc++;
+    }
+    while (!(msg instanceof DoneMsg));
+    final String className = msg.getClass().getCanonicalName();
+    assertEquals(msgc, 1, "Ending " + tn + " with incorrect message number :" + className);
+    assertTrue(msg instanceof DoneMsg,
+        "Ending " + tn + " with incorrect message type :" + className);
+  }
+
   /**
    * Objectives
    *   - Test that everything is ok with changes on 2 suffixes
@@ -680,8 +656,7 @@
       backend2 = initializeTestBackend(false, TEST_ROOT_DN_STRING2,
           TEST_BACKEND_ID2);
       backend2.setPrivateBackend(true);
-      SortedSet<String> replServers = new TreeSet<String>();
-      replServers.add("localhost:"+replicationServerPort);
+      SortedSet<String> replServers = newSet("localhost:" + replicationServerPort);
 
       DomainFakeCfg domainConf =
         new DomainFakeCfg(baseDn2,  1602, replServers);
@@ -703,26 +678,10 @@
 
       // Expect root entry returned
       List<SearchResultEntry> entries = searchOp.getSearchEntries();
-      assertEquals(entries.size(),2, "Entries number returned by search");
-      assertTrue(entries != null);
-      if (entries != null)
-      {
-        for (SearchResultEntry resultEntry : entries)
-        {
-          // Expect
-          debugInfo(tn, "Entry returned when test2 is public =" +
-              resultEntry.toLDIFString());
+      assertThat(entries).hasSize(2);
+      debugAndWriteEntries(null, entries, tn);
 
-          // Test entry attributes
-          //if (i==2)
-          //{
-          //  checkPossibleValues(resultEntry,"targetobjectclass","top","organization");
-          //}
-        }
-      }
-
-      eclCfg =
-        new ExternalChangelogDomainFakeCfg(false, null, null);
+      eclCfg = new ExternalChangelogDomainFakeCfg(false, null, null);
       domainConf.setExternalChangelogDomain(eclCfg);
       domain2.applyConfigurationChange(domainConf);
 
@@ -730,16 +689,9 @@
 
       // Expect only entry from o=test returned
       entries = searchOp.getSearchEntries();
-      assertTrue(entries != null, "Entries returned when test2 is ECL disabled.");
-      assertTrue(entries.size()==1, "#Entry="+entries.size()+"when expected is 1");
-      if (entries != null)
-      {
-        for (SearchResultEntry resultEntry : entries)
-        {
-          debugInfo(tn, "Entry returned when test2 is private ="
-              + resultEntry.toLDIFString());
-        }
-      }
+      assertThat(entries).hasSize(1);
+      entries.get(0);
+      debugAndWriteEntries(null, entries, tn);
 
       // Test lastExternalChangelogCookie attribute of the ECL
       // (does only refer to non private backend)
@@ -751,7 +703,6 @@
       assertTrue(expectedLastCookie.equalsTo(new MultiDomainServerState(lastCookie)),
           " Expected last cookie attribute value:" + expectedLastCookie +
           " Read from server: " + lastCookie + " are equal :");
-
     }
     finally
     {
@@ -833,31 +784,25 @@
 
       cookie="";
       List<SearchResultEntry> entries = searchOp.getSearchEntries();
-      if (entries != null)
+      assertThat(entries).hasSize(4);
+      debugAndWriteEntries(ldifWriter, entries, tn);
+      int i = 0;
+      for (SearchResultEntry entry : entries)
       {
-        int i=0;
-        for (SearchResultEntry entry : entries)
+        if (i++ == 2)
         {
-          debugInfo(tn, " RESULT entry returned:" + entry.toSingleLineString());
-          ldifWriter.writeEntry(entry);
-          if (i++==2)
-          {
-            // Store the cookie returned with the 3rd ECL entry returned to use
-            // it in the test below.
-            cookie =
-              entry.getAttribute("changelogcookie").get(0).iterator().next().toString();
-          }
+          // Store the cookie returned with the 3rd ECL entry returned to use
+          // it in the test below.
+          cookie = entry.getAttribute("changelogcookie").get(0).iterator().next().toString();
         }
       }
-      assertEquals(searchOp.getSearchEntries().size(), 4);
 
       // Now start from last cookie and expect to get ONLY the 4th change
       searchOp = searchOnCookieChangelog("(targetDN=*" + tn + "*)", cookie, tn, SUCCESS);
 
       // We expect the 4th change
       cookie = "";
-      cookie = getCookie(tn, ldifWriter, cookie, searchOp.getSearchEntries());
-      assertEquals(searchOp.getSearchEntries().size(), 1);
+      cookie = getCookie(searchOp.getSearchEntries(), 1, tn, ldifWriter, cookie);
 
       // Now publishes a new change and search from the previous cookie
       ChangeNumber cn5 = new ChangeNumber(time++, ts++, s1test.getServerId());
@@ -870,14 +815,12 @@
       // o=test2      msg3        msg2
 
       searchOp = searchOnCookieChangelog("(targetDN=*" + tn + "*)", cookie, tn, SUCCESS);
-      cookie = getCookie(tn, ldifWriter, cookie, searchOp.getSearchEntries());
-      assertEquals(searchOp.getSearchEntries().size(), 1);
+      cookie = getCookie(searchOp.getSearchEntries(), 1, tn, ldifWriter, cookie);
 
       cookie="";
       searchOp = searchOnCookieChangelog("(targetDN=*" + tn + "*,o=test)", cookie, tn, SUCCESS);
-      cookie = getCookie(tn, ldifWriter, cookie, searchOp.getSearchEntries());
       // we expect msg1 + msg4 + msg5
-      assertEquals(searchOp.getSearchEntries().size(), 3);
+      cookie = getCookie(searchOp.getSearchEntries(), 3, tn, ldifWriter, cookie);
 
       // Test startState ("first cookie") of the ECL
       // --
@@ -909,15 +852,14 @@
       ReplicationServerDomain rsd =
         replicationServer.getReplicationServerDomain(TEST_ROOT_DN_STRING, false);
       ServerState startState = rsd.getStartState();
-      assertTrue(startState.getChangeNumber(s1test.getServerId()).getSeqnum()==1);
+      assertEquals(startState.getChangeNumber(s1test.getServerId()).getSeqnum(), 1);
       assertTrue(startState.getChangeNumber(s2test.getServerId()) != null);
-      assertTrue(startState.getChangeNumber(s2test.getServerId()).getSeqnum()==7);
+      assertEquals(startState.getChangeNumber(s2test.getServerId()).getSeqnum(), 7);
 
-      rsd =
-        replicationServer.getReplicationServerDomain(TEST_ROOT_DN_STRING2, false);
+      rsd = replicationServer.getReplicationServerDomain(TEST_ROOT_DN_STRING2, false);
       startState = rsd.getStartState();
-      assertTrue(startState.getChangeNumber(s2test2.getServerId()).getSeqnum()==2);
-      assertTrue(startState.getChangeNumber(s1test2.getServerId()).getSeqnum()==6);
+      assertEquals(startState.getChangeNumber(s2test2.getServerId()).getSeqnum(), 2);
+      assertEquals(startState.getChangeNumber(s1test2.getServerId()).getSeqnum(), 6);
 
       // Test lastExternalChangelogCookie attribute of the ECL
       MultiDomainServerState expectedLastCookie =
@@ -932,8 +874,7 @@
       // Test invalid cookie
       cookie += ";o=test6:";
       debugInfo(tn, "Search with bad domain in cookie=" + cookie);
-      searchOp =
-          searchOnCookieChangelog("(targetDN=*" + tn + "*,o=test)", cookie, tn,
+      searchOp = searchOnCookieChangelog("(targetDN=*" + tn + "*,o=test)", cookie, tn,
               PROTOCOL_ERROR);
       assertEquals(searchOp.getSearchEntries().size(), 0);
       assertTrue(searchOp.getErrorMessage().toString().equals(
@@ -946,16 +887,14 @@
       // let's do a very quick test here.
       String newCookie = lastCookie + "o=test6:";
       debugInfo(tn, "Search with bad domain in cookie=" + cookie);
-      searchOp =
-          searchOnCookieChangelog("(targetDN=*" + tn + "*,o=test)", newCookie,
+      searchOp = searchOnCookieChangelog("(targetDN=*" + tn + "*,o=test)", newCookie,
               tn, UNWILLING_TO_PERFORM);
       assertEquals(searchOp.getSearchEntries().size(), 0);
 
       // Test missing domain in provided cookie
       newCookie = lastCookie.substring(lastCookie.indexOf(';')+1);
       debugInfo(tn, "Search with bad domain in cookie=" + cookie);
-      searchOp =
-          searchOnCookieChangelog("(targetDN=*" + tn + "*,o=test)", newCookie,
+      searchOp = searchOnCookieChangelog("(targetDN=*" + tn + "*,o=test)", newCookie,
               tn, UNWILLING_TO_PERFORM);
       assertEquals(searchOp.getSearchEntries().size(), 0);
       String expectedError = ERR_RESYNC_REQUIRED_MISSING_DOMAIN_IN_PROVIDED_COOKIE
@@ -972,24 +911,23 @@
     debugInfo(tn, "Ending test successfully");
   }
 
-  private String getCookie(String tn, LDIFWriter ldifWriter, String cookie,
-      List<SearchResultEntry> entries) throws Exception
+  private String getCookie(List<SearchResultEntry> entries,
+      int expectedNbEntries, String tn, LDIFWriter ldifWriter, String cookie)
+      throws Exception
   {
-    if (entries != null)
+    assertThat(entries).hasSize(expectedNbEntries);
+    debugAndWriteEntries(ldifWriter, entries, tn);
+
+    for (SearchResultEntry entry : entries)
     {
-      for (SearchResultEntry entry : entries)
+      try
       {
-        debugInfo(tn, "Result entry=\n" + entry.toLDIFString());
-        ldifWriter.writeEntry(entry);
-        try
-        {
-          // Store the cookie returned with the 4rd ECL entry returned to use
-          // it in the test below.
-          cookie =
-            entry.getAttribute("changelogcookie").get(0).iterator().next().toString();
-        }
-        catch(NullPointerException e)
-        {}
+        // Store the cookie returned with the 4rd ECL entry returned to use
+        // it in the test below.
+        cookie = entry.getAttribute("changelogcookie").get(0).iterator().next().toString();
+      }
+      catch (NullPointerException e)
+      {
       }
     }
     return cookie;
@@ -1074,11 +1012,9 @@
           DN.decode(TEST_ROOT_DN_STRING),  1201,
           100, replicationServerPort,
           brokerSessionTimeout, true);
-      int ts = 1;
 
-
-      ChangeNumber cn1 = new ChangeNumber(TimeThread.getTime(), ts++, 1201);
-      publishDeleteMsgInOTest(server01, cn1, tn, 1);
+      final ChangeNumber[] cns = generateChangeNumbers(4, 1201);
+      publishDeleteMsgInOTest(server01, cns[0], tn, 1);
 
       Thread.sleep(1000);
 
@@ -1086,11 +1022,8 @@
       String cookieNotEmpty = readLastCookie();
       debugInfo(tn, "Store cookie not empty=\"" + cookieNotEmpty + "\"");
 
-      cn1 = new ChangeNumber(TimeThread.getTime(), ts++, 1201);
-      publishDeleteMsgInOTest(server01, cn1, tn, 2);
-
-      cn1 = new ChangeNumber(TimeThread.getTime(), ts++, 1201);
-      publishDeleteMsgInOTest(server01, cn1, tn, 3);
+      publishDeleteMsgInOTest(server01, cns[1], tn, 2);
+      publishDeleteMsgInOTest(server01, cns[2], tn, 3);
 
       // Sleep longer than this delay - the changelog will be trimmed
       Thread.sleep(1000);
@@ -1114,17 +1047,9 @@
           searchOnCookieChangelog("(targetDN=*)", cookie, tn, SUCCESS);
 
       List<SearchResultEntry> entries = searchOp.getSearchEntries();
-      if (entries != null)
-      {
-        for (SearchResultEntry entry : entries)
-        {
-          debugInfo(tn, " RESULT entry returned:" + entry.toSingleLineString());
-          ldifWriter.writeEntry(entry);
-        }
-      }
-
       // Assert ECL is empty since replication changelog has been trimmed
-      assertEquals(searchOp.getSearchEntries().size(), 0);
+      assertThat(entries).hasSize(0);
+      debugAndWriteEntries(ldifWriter, entries, tn);
 
       // 4. Assert that a request with the current last cookie returns nothing
       cookie = readLastCookie();
@@ -1132,35 +1057,24 @@
       searchOp = searchOnCookieChangelog("(targetDN=*)", cookie, tn, SUCCESS);
 
       entries = searchOp.getSearchEntries();
-      if (entries != null)
-      {
-        for (SearchResultEntry entry : entries)
-        {
-          debugInfo(tn, " RESULT entry returned:" + entry.toSingleLineString());
-          ldifWriter.writeEntry(entry);
-        }
-      }
-
       // Assert ECL is empty since replication changelog has been trimmed
-      assertEquals(searchOp.getSearchEntries().size(), 0);
+      assertThat(entries).hasSize(0);
+      debugAndWriteEntries(ldifWriter, entries, tn);
+
 
       // ---
       // 5. Assert that a request with an "old" cookie - one that refers to
       //    changes that have been removed by the replication changelog trimming
       //    returns the appropriate error.
-
-      cn1 = new ChangeNumber(TimeThread.getTime(), ts++, 1201);
-      publishDeleteMsgInOTest(server01, cn1, tn, 1);
+      publishDeleteMsgInOTest(server01, cns[3], tn, 1);
 
       debugInfo(tn, "d1 trimdate" + d1.getStartState());
       debugInfo(tn, "d2 trimdate" + d2.getStartState());
       searchOp = searchOnCookieChangelog("(targetDN=*)", cookieNotEmpty, tn, UNWILLING_TO_PERFORM);
       assertEquals(searchOp.getSearchEntries().size(), 0);
       assertTrue(searchOp.getErrorMessage().toString().startsWith(
-          ERR_RESYNC_REQUIRED_TOO_OLD_DOMAIN_IN_PROVIDED_COOKIE.get("o=test")
-	  .toString()),
+          ERR_RESYNC_REQUIRED_TOO_OLD_DOMAIN_IN_PROVIDED_COOKIE.get("o=test").toString()),
           searchOp.getErrorMessage().toString());
-
     }
     finally
     {
@@ -1180,29 +1094,44 @@
     debugInfo(tn, "Ending test successfully");
   }
 
+  private void debugAndWriteEntries(LDIFWriter ldifWriter,
+      List<SearchResultEntry> entries, String tn) throws Exception
+  {
+    if (entries != null)
+    {
+      for (SearchResultEntry entry : entries)
+      {
+        // Can use entry.toSingleLineString()
+        debugInfo(tn, " RESULT entry returned:" + entry.toLDIFString());
+        if (ldifWriter != null)
+        {
+          ldifWriter.writeEntry(entry);
+        }
+      }
+    }
+  }
+
   private String readLastCookie() throws Exception
   {
     String cookie = "";
     LDIFWriter ldifWriter = getLDIFWriter();
 
-    Set<String> lastcookieattribute = new LinkedHashSet<String>();
-    lastcookieattribute.add("lastExternalChangelogCookie");
+    Set<String> lastcookieattribute = newSet("lastExternalChangelogCookie");
 
+    InternalSearchOperation searchOp = searchOnRootDSE(lastcookieattribute);
+    List<SearchResultEntry> entries = searchOp.getSearchEntries();
+    if (entries != null)
     {
-      InternalSearchOperation searchOp = searchOnRootDSE(lastcookieattribute);
-      List<SearchResultEntry> entries = searchOp.getSearchEntries();
-      if (entries != null)
+      for (SearchResultEntry resultEntry : entries)
       {
-        for (SearchResultEntry resultEntry : entries)
+        ldifWriter.writeEntry(resultEntry);
+        try
         {
-          ldifWriter.writeEntry(resultEntry);
-          try
-          {
-            List<Attribute> l = resultEntry.getAttribute("lastexternalchangelogcookie");
-            cookie = l.get(0).iterator().next().toString();
-          }
-          catch(NullPointerException e)
-          {}
+          List<Attribute> l = resultEntry.getAttribute("lastexternalchangelogcookie");
+          cookie = l.get(0).iterator().next().toString();
+        }
+        catch (NullPointerException e)
+        {
         }
       }
     }
@@ -1223,7 +1152,6 @@
           DN.decode(TEST_ROOT_DN_STRING),  1201,
           100, replicationServerPort,
           brokerSessionTimeout, true);
-      int ts = 1;
 
       // Creates broker on o=test2
       ReplicationBroker server02 = openReplicationSession(
@@ -1234,19 +1162,20 @@
       String user1entryUUID = "11111111-1111-1111-1111-111111111111";
       String baseUUID       = "22222222-2222-2222-2222-222222222222";
 
+      ChangeNumber[] cns = generateChangeNumbers(4, 1201);
 
       // Publish DEL
-      ChangeNumber cn1 = new ChangeNumber(TimeThread.getTime(), ts++, 1201);
-      publishDeleteMsgInOTest(server01, cn1, tn, 1);
+      int cnCounter = 0;
+      publishDeleteMsgInOTest(server01, cns[cnCounter], tn, cnCounter + 1);
 
       // Publish ADD
-      ChangeNumber cn2 = new ChangeNumber(TimeThread.getTime(), ts++, 1201);
+      cnCounter++;
       String lentry = "dn: uid="+tn+"2," + TEST_ROOT_DN_STRING + "\n"
           + "objectClass: top\n" + "objectClass: domain\n"
           + "entryUUID: "+user1entryUUID+"\n";
       Entry entry = TestCaseUtils.entryFromLdifString(lentry);
       AddMsg addMsg = new AddMsg(
-          cn2,
+          cns[cnCounter],
           "uid="+tn+"2," + TEST_ROOT_DN_STRING,
           user1entryUUID,
           baseUUID,
@@ -1256,32 +1185,24 @@
       server01.publish(addMsg);
       debugInfo(tn, " publishes " + addMsg.getChangeNumber());
 
-      // Publish DEL
-      /*
-      ChangeNumber cn12 = new ChangeNumber(TimeThread.getTime(), ts++, 1202);
-      DeleteMsg delMsg2 =
-        new DeleteMsg("uid="+tn+"12," + TEST_ROOT_DN_STRING2, cn12, tn+"uuid12");
-      server02.publish(delMsg2);
-      debugInfo(tn, " publishes " + delMsg2.getChangeNumber());
-      */
-
       // Publish MOD
-      ChangeNumber cn3 = new ChangeNumber(TimeThread.getTime(), ts++, 1201);
+      cnCounter++;
+      DN baseDN = DN.decode("uid=" + tn + "3," + TEST_ROOT_DN_STRING);
       List<Modification> mods = createMods("description", "new value");
-      ModifyMsg modMsg = new ModifyMsg(cn3, DN
-          .decode("uid="+tn+"3," + TEST_ROOT_DN_STRING), mods, tn+"uuid3");
+      ModifyMsg modMsg = new ModifyMsg(cns[cnCounter], baseDN, mods, tn + "uuid3");
       server01.publish(modMsg);
       debugInfo(tn, " publishes " + modMsg.getChangeNumber());
 
       // Publish modDN
-      DN newSuperior = DN.decode(TEST_ROOT_DN_STRING2);
-      ChangeNumber cn4 = new ChangeNumber(TimeThread.getTime(), ts++, 1201);
+      cnCounter++;
+      final DN newSuperior = DN.decode(TEST_ROOT_DN_STRING2);
       ModifyDNOperation op = new ModifyDNOperationBasis(connection, 1, 1, null,
           DN.decode("uid="+tn+"4," + TEST_ROOT_DN_STRING), // entryDN
           RDN.decode("uid="+tn+"new4"), // new rdn
           true,  // deleteoldrdn
           newSuperior);
-      op.setAttachment(SYNCHROCONTEXT, new ModifyDnContext(cn4, tn+"uuid4", "newparentId"));
+      op.setAttachment(SYNCHROCONTEXT, new ModifyDnContext(cns[cnCounter],
+          tn + "uuid4", "newparentId"));
       LocalBackendModifyDNOperation localOp = new LocalBackendModifyDNOperation(op);
       ModifyDNMsg modDNMsg = new ModifyDNMsg(localOp);
       server01.publish(modDNMsg);
@@ -1293,75 +1214,53 @@
           searchOnCookieChangelog("(targetdn=*" + tn + "*,o=test)", cookie, tn, SUCCESS);
 
       // test 4 entries returned
-      String cookie1 = "o=test:" + cn1 + ";";
-      String cookie2 = "o=test:" + cn2 + ";";
-      String cookie3 = "o=test:" + cn3 + ";";
-      String cookie4 = "o=test:" + cn4 + ";";
+      final String[] cookies = new String[4];
+      for (int j = 0; j < cookies.length; j++)
+      {
+        cookies[j] = "o=test:" + cns[j] + ";";
+      }
 
       assertEquals(searchOp.getSearchEntries().size(), 4);
       List<SearchResultEntry> entries = searchOp.getSearchEntries();
+      debugAndWriteEntries(ldifWriter, entries, tn);
+
       if (entries != null)
       {
         int i=0;
         for (SearchResultEntry resultEntry : entries)
         {
           i++;
-          debugInfo(tn, "Result entry returned:" + resultEntry.toLDIFString());
-          ldifWriter.writeEntry(resultEntry);
+          checkDn(cns[i - 1], resultEntry);
+          checkValue(resultEntry, "targetdn", "uid=" + tn + i + "," + TEST_ROOT_DN_STRING);
+          checkValue(resultEntry, "replicationcsn", cns[i - 1].toString());
+          checkValue(resultEntry, "replicaidentifier", "1201");
+          checkValue(resultEntry, "changelogcookie", cookies[i - 1]);
+          checkValue(resultEntry, "changenumber", "0");
+
           if (i==1)
           {
-            // check the DEL entry has the right content
-            assertTrue(resultEntry.getDN().toNormalizedString().equalsIgnoreCase(
-                "replicationcsn=" + cn1 + "," + TEST_ROOT_DN_STRING + ",cn=changelog"));
-            checkValue(resultEntry,"replicationcsn",cn1.toString());
-            checkValue(resultEntry,"replicaidentifier","1201");
-            checkValue(resultEntry,"targetdn","uid="+tn+"1," + TEST_ROOT_DN_STRING);
-            checkValue(resultEntry,"changetype","delete");
-            checkValue(resultEntry,"changelogcookie",cookie1);
+            checkValue(resultEntry, "changetype", "delete");
             checkValue(resultEntry,"targetentryuuid",tn+"uuid1");
-            checkValue(resultEntry,"changenumber","0");
           } else if (i==2)
           {
-            // check the ADD entry has the right content
-            assertTrue(resultEntry.getDN().toNormalizedString().equalsIgnoreCase(
-                "replicationcsn=" + cn2 + "," + TEST_ROOT_DN_STRING + ",cn=changelog"));
-            String expectedValue1 = "objectClass: domain\nobjectClass: top\n" +
-            "entryUUID: 11111111-1111-1111-1111-111111111111\n";
-            String expectedValue2 = "entryUUID: 11111111-1111-1111-1111-111111111111\n" +
-            "objectClass: domain\nobjectClass: top\n";
+            checkValue(resultEntry, "changetype", "add");
+            String expectedValue1 = "objectClass: domain\nobjectClass: top\n"
+                + "entryUUID: 11111111-1111-1111-1111-111111111111\n";
+            String expectedValue2 = "entryUUID: 11111111-1111-1111-1111-111111111111\n"
+                + "objectClass: domain\nobjectClass: top\n";
             checkPossibleValues(resultEntry,"changes",expectedValue1, expectedValue2);
-            checkValue(resultEntry,"replicationcsn",cn2.toString());
-            checkValue(resultEntry,"replicaidentifier","1201");
-            checkValue(resultEntry,"targetdn","uid="+tn+"2," + TEST_ROOT_DN_STRING);
-            checkValue(resultEntry,"changetype","add");
-            checkValue(resultEntry,"changelogcookie",cookie2);
             checkValue(resultEntry,"targetentryuuid",user1entryUUID);
-            checkValue(resultEntry,"changenumber","0");
           } else if (i==3)
           {
             // check the MOD entry has the right content
-            assertTrue(resultEntry.getDN().toNormalizedString().equalsIgnoreCase(
-                "replicationcsn=" + cn3 + "," + TEST_ROOT_DN_STRING + ",cn=changelog"));
-            String expectedValue = "replace: description\n" +
-            "description: new value\n-\n";
+            checkValue(resultEntry, "changetype", "modify");
+            String expectedValue =
+                "replace: description\n" + "description: new value\n-\n";
             checkValue(resultEntry,"changes",expectedValue);
-            checkValue(resultEntry,"replicationcsn",cn3.toString());
-            checkValue(resultEntry,"replicaidentifier","1201");
-            checkValue(resultEntry,"targetdn","uid="+tn+"3," + TEST_ROOT_DN_STRING);
-            checkValue(resultEntry,"changetype","modify");
-            checkValue(resultEntry,"changelogcookie",cookie3);
             checkValue(resultEntry,"targetentryuuid",tn+"uuid3");
-            checkValue(resultEntry,"changenumber","0");
           } else if (i==4)
           {
-            // check the MODDN entry has the right content
-            assertTrue(resultEntry.getDN().toNormalizedString().equalsIgnoreCase(
-                "replicationcsn=" + cn4 + "," + TEST_ROOT_DN_STRING + ",cn=changelog"));
-            checkValue(resultEntry,"replicationcsn",cn4.toString());
-            checkValue(resultEntry,"replicaidentifier","1201");
-            checkValue(resultEntry,"targetdn","uid="+tn+"4," + TEST_ROOT_DN_STRING);
             checkValue(resultEntry,"changetype","modrdn");
-            checkValue(resultEntry,"changelogcookie",cookie4);
             checkValue(resultEntry,"targetentryuuid",tn+"uuid4");
             checkValue(resultEntry,"newrdn","uid=ECLAllOpsnew4");
             if (newSuperior != null)
@@ -1369,7 +1268,6 @@
               checkValue(resultEntry, "newsuperior", TEST_ROOT_DN_STRING2);
             }
             checkValue(resultEntry,"deleteoldrdn","true");
-            checkValue(resultEntry,"changenumber","0");
           }
         }
       }
@@ -1379,16 +1277,34 @@
       debugInfo(tn, "Entries:" + result);
 
       List<String> ctrlList = getControls(result);
-      assertTrue(ctrlList.get(0).equals(cookie1));
-      assertTrue(ctrlList.get(1).equals(cookie2));
-      assertTrue(ctrlList.get(2).equals(cookie3));
-      assertTrue(ctrlList.get(3).equals(cookie4));
+      assertThat(ctrlList).containsExactly(cookies);
 
       stop(server01, server02);
     }
     debugInfo(tn, "Ending test with success");
   }
 
+  private ChangeNumber[] generateChangeNumbers(int nb, int serverId)
+  {
+    long startTime = TimeThread.getTime();
+
+    ChangeNumber[] cns = new ChangeNumber[nb];
+    for (int i = 0; i < nb; i++)
+    {
+      // seqNum must be greater than 0, so start at 1
+      cns[i] = new ChangeNumber(startTime + i, i + 1, serverId);
+    }
+    return cns;
+  }
+
+  private void checkDn(ChangeNumber cn, SearchResultEntry resultEntry)
+  {
+    String actualDN = resultEntry.getDN().toNormalizedString();
+    String expectedDN =
+        "replicationcsn=" + cn + "," + TEST_ROOT_DN_STRING + ",cn=changelog";
+    assertThat(actualDN).isEqualToIgnoringCase(expectedDN);
+  }
+
   protected List<String> getControls(String resultString)
   {
     StringReader r=new StringReader(resultString);
@@ -1510,27 +1426,16 @@
   private static void checkValues(Entry entry, String attrName,
       Set<String> expectedValues)
   {
-    int i=0;
-    try
+    for (Attribute a : entry.getAttribute(attrName))
     {
-      List<Attribute> attrs = entry.getAttribute(attrName);
-      for (Attribute a : attrs)
+      for (AttributeValue av : a)
       {
-        for (AttributeValue av : a)
-        {
-          String encodedValue = av.toString();
-          assertTrue(
-              expectedValues.contains(encodedValue),
-              "In entry " + entry + " attr <" + attrName + "> equals " +
-              av + " instead of one of the expected values " + expectedValues);
-          i++;
-        }
+        String encodedValue = av.toString();
+        assertTrue(expectedValues.contains(encodedValue), "In entry " + entry
+            + " attr <" + attrName + "> equals " + av
+            + " instead of one of the expected values " + expectedValues);
       }
     }
-    catch(NoSuchElementException e)
-    {
-      assertTrue(i==expectedValues.size());
-    }
   }
 
   /**
@@ -1562,12 +1467,12 @@
           DN.decode(TEST_ROOT_DN_STRING),  1201,
           100, replicationServerPort,
           brokerSessionTimeout, true);
-      int ts = 1;
+
+      ChangeNumber[] cns = generateChangeNumbers(2, 1201);
 
       // Produce update on this suffix
-      ChangeNumber cn = new ChangeNumber(TimeThread.getTime(), ts++, 1201);
       DeleteMsg delMsg =
-        new DeleteMsg("uid=" + tn + "1," + TEST_ROOT_DN_STRING, cn,
+          new DeleteMsg("uid=" + tn + "1," + TEST_ROOT_DN_STRING, cns[0],
             "11111111-1112-1113-1114-111111111114");
       debugInfo(tn, " publishing " + delMsg.getChangeNumber());
       server01.publish(delMsg);
@@ -1677,7 +1582,7 @@
       }
 
       // Produces change 2
-      cn = new ChangeNumber(TimeThread.getTime(), ts++, 1201);
+      final ChangeNumber cn = cns[1];
       String expectedDn = "uid=" + tn + "2," +  TEST_ROOT_DN_STRING;
       delMsg = new DeleteMsg(expectedDn, cn,
          "11111111-1112-1113-1114-111111111115");
@@ -1799,7 +1704,7 @@
           }
         }
         // search should end with success
-        assertTrue(searchesDone==1);
+        assertEquals(searchesDone, 1);
         // but returning no entry
         assertEquals(searchEntries,0, "Bad search entry# in ACI test of " + tn);
       }
@@ -2521,24 +2426,20 @@
     String tn = "ECLCompatEmpty";
     debugInfo(tn, "Starting test\n\n");
 
-    {
-      // search on 'cn=changelog'
-      String filter = "(objectclass=*)";
-      debugInfo(tn, " Search: " + filter);
-      InternalSearchOperation op = connection.processSearch(
-          ByteString.valueOf("cn=changelog"),
-          SearchScope.WHOLE_SUBTREE,
-          LDAPFilter.decode(filter));
+    // search on 'cn=changelog'
+    String filter = "(objectclass=*)";
+    debugInfo(tn, " Search: " + filter);
+    InternalSearchOperation op = connection.processSearch(
+        ByteString.valueOf("cn=changelog"),
+        SearchScope.WHOLE_SUBTREE,
+        LDAPFilter.decode(filter));
 
-      // success
-      assertEquals(
-          op.getResultCode(), ResultCode.SUCCESS,
-          op.getErrorMessage().toString());
+    // success
+    assertEquals(op.getResultCode(), ResultCode.SUCCESS, op.getErrorMessage().toString());
 
-      // root entry returned
-      assertEquals(op.getEntriesSent(), 1);
-      debugInfo(tn, "Ending test successfully");
-    }
+    // root entry returned
+    assertEquals(op.getEntriesSent(), 1);
+    debugInfo(tn, "Ending test successfully");
   }
 
   private int ECLCompatWriteReadAllOps(int firstDraftChangeNumber)
@@ -2546,7 +2447,7 @@
   {
     String tn = "ECLCompatWriteReadAllOps/" + firstDraftChangeNumber;
     debugInfo(tn, "Starting test\n\n");
-    int ts = 1;
+    final int nbChanges = 4;
 
     {
       LDIFWriter ldifWriter = getLDIFWriter();
@@ -2560,17 +2461,17 @@
       String user1entryUUID = "11111111-1112-1113-1114-111111111115";
       String baseUUID       = "22222222-2222-2222-2222-222222222222";
 
+      ChangeNumber[] cns = generateChangeNumbers(nbChanges, 1201);
+      gblCN = cns[1];
 
       // Publish DEL
-      ChangeNumber cn1 = new ChangeNumber(TimeThread.getTime(), ts++, 1201);
       DeleteMsg delMsg =
-        new DeleteMsg("uid="+tn+"1," + TEST_ROOT_DN_STRING, cn1,
+          new DeleteMsg("uid=" + tn + "1," + TEST_ROOT_DN_STRING, cns[0],
             user1entryUUID);
       server01.publish(delMsg);
       debugInfo(tn, " publishes " + delMsg.getChangeNumber());
 
       // Publish ADD
-      gblCN = new ChangeNumber(TimeThread.getTime(), ts++, 1201);
       String lentry =
           "dn: uid="+tn+"2," + TEST_ROOT_DN_STRING + "\n"
           + "objectClass: top\n"
@@ -2589,21 +2490,19 @@
       debugInfo(tn, " publishes " + addMsg.getChangeNumber());
 
       // Publish MOD
-      ChangeNumber cn3 = new ChangeNumber(TimeThread.getTime(), ts++, 1201);
+      DN baseDN = DN.decode("uid="+tn+"3," + TEST_ROOT_DN_STRING);
       List<Modification> mods = createMods("description", "new value");
-      ModifyMsg modMsg = new ModifyMsg(cn3, DN
-          .decode("uid="+tn+"3," + TEST_ROOT_DN_STRING), mods, user1entryUUID);
+      ModifyMsg modMsg = new ModifyMsg(cns[2], baseDN, mods, user1entryUUID);
       server01.publish(modMsg);
       debugInfo(tn, " publishes " + modMsg.getChangeNumber());
 
       // Publish modDN
-      ChangeNumber cn4 = new ChangeNumber(TimeThread.getTime(), ts++, 1201);
       ModifyDNOperation op = new ModifyDNOperationBasis(connection, 1, 1, null,
           DN.decode("uid="+tn+"4," + TEST_ROOT_DN_STRING), // entryDN
           RDN.decode("uid="+tn+"new4"), // new rdn
           true,  // deleteoldrdn
           DN.decode(TEST_ROOT_DN_STRING2)); // new superior
-      op.setAttachment(SYNCHROCONTEXT, new ModifyDnContext(cn4, user1entryUUID, "newparentId"));
+      op.setAttachment(SYNCHROCONTEXT, new ModifyDnContext(cns[3], user1entryUUID, "newparentId"));
       LocalBackendModifyDNOperation localOp = new LocalBackendModifyDNOperation(op);
       ModifyDNMsg modDNMsg = new ModifyDNMsg(localOp);
       server01.publish(modDNMsg);
@@ -2614,114 +2513,85 @@
       InternalSearchOperation searchOp = searchOnChangelog(filter, tn, SUCCESS);
 
       // test 4 entries returned
-      List<SearchResultEntry> entries = searchOp.getSearchEntries();
-      // 4 entries expected
-      assertEquals(searchOp.getSearchEntries().size(), 4);
-      if (entries != null)
-      {
-        assertEntries(firstDraftChangeNumber, tn, ldifWriter, user1entryUUID,
-            cn1, cn3, cn4, entries);
-      }
+      assertEntries(searchOp.getSearchEntries(), firstDraftChangeNumber, tn,
+          ldifWriter, user1entryUUID, cns[0], gblCN, cns[2], cns[3]);
       server01.stop();
 
       // Test with filter on draft changenumber
       filter = "(&(targetdn=*"+tn.toLowerCase()+"*,o=test)(&(changenumber>="+
-      firstDraftChangeNumber+")(changenumber<="+(firstDraftChangeNumber+3)+")))";
+          firstDraftChangeNumber+")(changenumber<="+(firstDraftChangeNumber+3)+")))";
       searchOp = searchOnChangelog(filter, tn, SUCCESS);
 
-      entries = searchOp.getSearchEntries();
-
-      if (entries != null)
-      {
-        assertEntries(firstDraftChangeNumber, tn, ldifWriter, user1entryUUID,
-            cn1, cn3, cn4, entries);
-      }
-      assertEquals(searchOp.getSearchEntries().size(), 4);
+      assertEntries(searchOp.getSearchEntries(), firstDraftChangeNumber, tn,
+          ldifWriter, user1entryUUID, cns[0], gblCN, cns[2], cns[3]);
+      assertEquals(searchOp.getSearchEntries().size(), nbChanges);
     }
     debugInfo(tn, "Ending test with success");
-    return ts;
+    return nbChanges;
   }
 
-  private void assertEntries(int firstDraftChangeNumber, String tn,
-      LDIFWriter ldifWriter, String user1entryUUID, ChangeNumber cn1,
-      ChangeNumber cn3, ChangeNumber cn4, List<SearchResultEntry> entries)
-      throws IOException, LDIFException
+  private void assertEntries(List<SearchResultEntry> entries,
+      int firstDraftChangeNumber, String tn, LDIFWriter ldifWriter,
+      String user1entryUUID, ChangeNumber... cns) throws Exception
   {
+    debugAndWriteEntries(ldifWriter, entries, tn);
+    assertEquals(entries.size(), 4);
+
     int i=0;
     for (SearchResultEntry resultEntry : entries)
     {
       i++;
-      debugInfo(tn, "Result entry returned:" + resultEntry.toLDIFString());
-      ldifWriter.writeEntry(resultEntry);
+
+      assertDnEquals(resultEntry, firstDraftChangeNumber, i - 1);
+      checkValue(resultEntry, "changenumber", String.valueOf(firstDraftChangeNumber + i - 1));
+      checkValue(resultEntry, "targetentryuuid", user1entryUUID);
+      checkValue(resultEntry, "replicaidentifier", "1201");
+      final ChangeNumber cn = cns[i - 1];
+      checkValue(resultEntry, "replicationcsn", cn.toString());
+      checkValue(resultEntry, "changelogcookie", "o=test:" + cn + ";");
+      checkValue(resultEntry, "targetdn", "uid=" + tn + i + "," + TEST_ROOT_DN_STRING);
+
       if (i==1)
       {
         // check the DEL entry has the right content
-        assertTrue(resultEntry.getDN().toNormalizedString().equalsIgnoreCase(
-            "changenumber="+String.valueOf(firstDraftChangeNumber+0)+",cn=changelog"),
-            "Result entry DN : actual=" + resultEntry.getDN().toNormalizedString() +
-            " expected=" + "changenumber="+String.valueOf(firstDraftChangeNumber+0)+",cn=changelog");
-        checkValue(resultEntry,"replicationcsn",cn1.toString());
-        checkValue(resultEntry,"replicaidentifier","1201");
-        checkValue(resultEntry,"targetdn","uid="+tn+"1," + TEST_ROOT_DN_STRING);
         checkValue(resultEntry,"changetype","delete");
-        checkValue(resultEntry, "changelogcookie", "o=test:" + cn1 + ";");
-        checkValue(resultEntry,"targetentryuuid",user1entryUUID);
-        checkValue(resultEntry,"changenumber",String.valueOf(firstDraftChangeNumber+0));
         checkValue(resultEntry,"targetuniqueid",user1entryUUID);
       } else if (i==2)
       {
         // check the ADD entry has the right content
-        assertTrue(resultEntry.getDN().toNormalizedString().equalsIgnoreCase(
-            "changenumber="+String.valueOf(firstDraftChangeNumber+1)+",cn=changelog"));
-        String expectedValue1 = "objectClass: domain\nobjectClass: top\n" +
-        "entryUUID: "+user1entryUUID+"\n";
-        String expectedValue2 = "entryUUID: "+user1entryUUID+"\n" +
-        "objectClass: domain\nobjectClass: top\n";
+        checkValue(resultEntry, "changetype", "add");
+        String expectedValue1 = "objectClass: domain\nobjectClass: top\n"
+            + "entryUUID: " + user1entryUUID + "\n";
+        String expectedValue2 = "entryUUID: " + user1entryUUID + "\n"
+            + "objectClass: domain\nobjectClass: top\n";
         checkPossibleValues(resultEntry,"changes",expectedValue1, expectedValue2);
-        checkValue(resultEntry,"replicationcsn",gblCN.toString());
-        checkValue(resultEntry,"replicaidentifier","1201");
-        checkValue(resultEntry,"targetdn","uid="+tn+"2," + TEST_ROOT_DN_STRING);
-        checkValue(resultEntry,"changetype","add");
-        checkValue(resultEntry, "changelogcookie", "o=test:" + gblCN + ";");
-        checkValue(resultEntry,"targetentryuuid",user1entryUUID);
-        checkValue(resultEntry,"changenumber",String.valueOf(firstDraftChangeNumber+1));
       } else if (i==3)
       {
         // check the MOD entry has the right content
-        assertTrue(resultEntry.getDN().toNormalizedString().equalsIgnoreCase(
-            "changenumber="+String.valueOf(firstDraftChangeNumber+2)+",cn=changelog"));
-        String expectedValue = "replace: description\n" +
-        "description: new value\n-\n";
+        checkValue(resultEntry, "changetype", "modify");
+        final String expectedValue = "replace: description\n" + "description: new value\n-\n";
         checkValue(resultEntry,"changes",expectedValue);
-        checkValue(resultEntry,"replicationcsn",cn3.toString());
-        checkValue(resultEntry,"replicaidentifier","1201");
-        checkValue(resultEntry,"targetdn","uid="+tn+"3," + TEST_ROOT_DN_STRING);
-        checkValue(resultEntry,"changetype","modify");
-        checkValue(resultEntry, "changelogcookie", "o=test:" + cn3 + ";");
-        checkValue(resultEntry,"targetentryuuid",user1entryUUID);
-        checkValue(resultEntry,"changenumber",String.valueOf(firstDraftChangeNumber+2));
       } else if (i==4)
       {
         // check the MODDN entry has the right content
-        assertTrue(resultEntry.getDN().toNormalizedString().equalsIgnoreCase(
-            "changenumber="+String.valueOf(firstDraftChangeNumber+3)+",cn=changelog"));
-        checkValue(resultEntry,"replicationcsn",cn4.toString());
-        checkValue(resultEntry,"replicaidentifier","1201");
-        checkValue(resultEntry,"targetdn","uid="+tn+"4," + TEST_ROOT_DN_STRING);
-        checkValue(resultEntry,"changetype","modrdn");
-        checkValue(resultEntry, "changelogcookie", "o=test:" + cn4 + ";");
-        checkValue(resultEntry,"targetentryuuid",user1entryUUID);
+        checkValue(resultEntry, "changetype", "modrdn");
         checkValue(resultEntry,"newrdn","uid="+tn+"new4");
         checkValue(resultEntry,"newsuperior",TEST_ROOT_DN_STRING2);
         checkValue(resultEntry,"deleteoldrdn","true");
-        checkValue(resultEntry,"changenumber",String.valueOf(firstDraftChangeNumber+3));
       }
     }
   }
 
+  private void assertDnEquals(SearchResultEntry resultEntry, int draftCN, int i)
+  {
+    String actualDN = resultEntry.getDN().toNormalizedString();
+    String expectedDN = "changenumber=" + (draftCN + i) + ",cn=changelog";
+    assertThat(actualDN).isEqualToIgnoringCase(expectedDN);
+  }
+
   private void ECLCompatReadFrom(int firstDraftChangeNumber) throws Exception
   {
-    String tn = "ECLCompatReadFrom/" + String.valueOf(firstDraftChangeNumber);
+    String tn = "ECLCompatReadFrom/" + firstDraftChangeNumber;
     debugInfo(tn, "Starting test\n\n");
 
     {
@@ -2739,24 +2609,19 @@
       InternalSearchOperation searchOp = searchOnChangelog(filter, tn, SUCCESS);
 
       List<SearchResultEntry> entries = searchOp.getSearchEntries();
-      assertEquals(searchOp.getSearchEntries().size(), 1);
-      if (entries != null)
-      {
-        for (SearchResultEntry resultEntry : entries)
-        {
-          debugInfo(tn, "Result entry returned:" + resultEntry.toLDIFString());
-          ldifWriter.writeEntry(resultEntry);
-          // check the entry has the right content
-          assertTrue("changenumber=6,cn=changelog".equalsIgnoreCase(resultEntry
-              .getDN().toNormalizedString()));
-          checkValue(resultEntry,"replicationcsn",gblCN.toString());
-          checkValue(resultEntry,"replicaidentifier","1201");
-          checkValue(resultEntry,"changetype","add");
-          checkValue(resultEntry,"changelogcookie","o=test:" + gblCN + ";");
-          checkValue(resultEntry,"targetentryuuid",user1entryUUID);
-          checkValue(resultEntry,"changenumber","6");
-        }
-      }
+      assertEquals(entries.size(), 1);
+      debugAndWriteEntries(ldifWriter, entries, tn);
+
+      // check the entry has the right content
+      SearchResultEntry resultEntry = entries.get(0);
+      assertTrue("changenumber=6,cn=changelog".equalsIgnoreCase(resultEntry.getDN().toNormalizedString()));
+      checkValue(resultEntry, "replicationcsn", gblCN.toString());
+      checkValue(resultEntry, "replicaidentifier", "1201");
+      checkValue(resultEntry, "changetype", "add");
+      checkValue(resultEntry, "changelogcookie", "o=test:" + gblCN + ";");
+      checkValue(resultEntry, "targetentryuuid", user1entryUUID);
+      checkValue(resultEntry, "changenumber", "6");
+
       server01.stop();
     }
     debugInfo(tn, "Ending test with success");
@@ -2771,29 +2636,22 @@
     String tn = "ECLCompatNoControl/" + firstDraftChangeNumber;
     debugInfo(tn, "Starting test\n\n");
 
-    {
-      // Creates broker on o=test
-      ReplicationBroker server01 = openReplicationSession(
-          DN.decode(TEST_ROOT_DN_STRING),  1201,
-          100, replicationServerPort,
-          brokerSessionTimeout, true);
+    // Creates broker on o=test
+    ReplicationBroker server01 =
+        openReplicationSession(DN.decode(TEST_ROOT_DN_STRING), 1201, 100,
+            replicationServerPort, brokerSessionTimeout, true);
 
-      String filter = "(changenumber="+firstDraftChangeNumber+")";
-      InternalSearchOperation searchOp = searchOnChangelog(filter, tn, SUCCESS);
+    String filter = "(changenumber=" + firstDraftChangeNumber + ")";
+    InternalSearchOperation searchOp = searchOnChangelog(filter, tn, SUCCESS);
 
-      List<SearchResultEntry> entries = searchOp.getSearchEntries();
-      assertEquals(searchOp.getSearchEntries().size(), 1);
-      if (entries != null)
-      {
-        for (SearchResultEntry resultEntry : entries)
-        {
-          // Just verify that no entry contains the ChangeLogCookie control
-          List<Control> controls = resultEntry.getControls();
-          assertTrue(controls.isEmpty());
-        }
-      }
-      server01.stop();
-    }
+    List<SearchResultEntry> entries = searchOp.getSearchEntries();
+    assertEquals(entries.size(), 1);
+    // Just verify that no entry contains the ChangeLogCookie control
+    List<Control> controls = entries.get(0).getControls();
+    assertTrue(controls.isEmpty());
+
+    server01.stop();
+
     debugInfo(tn, "Ending test with success");
   }
 
@@ -2807,23 +2665,16 @@
   private void ECLCompatReadFromTo(int firstDraftChangeNumber,
       int lastDraftChangeNumber) throws Exception
   {
-    String tn = "ECLCompatReadFromTo/" + firstDraftChangeNumber + "/"
-            + lastDraftChangeNumber;
+    String tn = "ECLCompatReadFromTo/" + firstDraftChangeNumber + "/" + lastDraftChangeNumber;
     debugInfo(tn, "Starting test\n\n");
 
-    {
-      String filter = "(&(changenumber>="+firstDraftChangeNumber+")(changenumber<="+lastDraftChangeNumber+"))";
-      InternalSearchOperation searchOp = searchOnChangelog(filter, tn, SUCCESS);
-      assertEquals(searchOp.getSearchEntries().size(),
-          lastDraftChangeNumber-firstDraftChangeNumber+1);
-      if (searchOp.getSearchEntries() != null)
-      {
-        for (SearchResultEntry resultEntry : searchOp.getSearchEntries())
-        {
-          debugInfo(tn, "Result entry returned:" + resultEntry.toLDIFString());
-        }
-      }
-    }
+    String filter = "(&(changenumber>=" + firstDraftChangeNumber + ")" +
+        "(changenumber<="+ lastDraftChangeNumber + "))";
+    InternalSearchOperation searchOp = searchOnChangelog(filter, tn, SUCCESS);
+    assertEquals(searchOp.getSearchEntries().size(),
+        lastDraftChangeNumber - firstDraftChangeNumber + 1);
+    debugAndWriteEntries(null, searchOp.getSearchEntries(), tn);
+
     debugInfo(tn, "Ending test with success");
   }
 
@@ -2850,27 +2701,21 @@
     String tn = "ECLFilterOnReplicationCsn";
     debugInfo(tn, "Starting test\n\n");
 
-    {
-      LDIFWriter ldifWriter = getLDIFWriter();
+    LDIFWriter ldifWriter = getLDIFWriter();
 
-      String filter = "(replicationcsn="+this.gblCN+")";
-      InternalSearchOperation searchOp = searchOnChangelog(filter, tn, SUCCESS);
-      assertEquals(searchOp.getSearchEntries().size(), 1);
+    String filter = "(replicationcsn=" + this.gblCN + ")";
+    InternalSearchOperation searchOp = searchOnChangelog(filter, tn, SUCCESS);
+    assertEquals(searchOp.getSearchEntries().size(), 1);
 
-      List<SearchResultEntry> entries = searchOp.getSearchEntries();
-      assertEquals(searchOp.getSearchEntries().size(), 1);
-      if (entries != null)
-      {
-        for (SearchResultEntry resultEntry : entries)
-        {
-          debugInfo(tn, "Result entry returned:" + resultEntry.toLDIFString());
-          ldifWriter.writeEntry(resultEntry);
-          // check the DEL entry has the right content
-          checkValue(resultEntry,"replicationcsn",gblCN.toString());
-          // TODO:ECL check values of the other attributes
-        }
-      }
-    }
+    List<SearchResultEntry> entries = searchOp.getSearchEntries();
+    assertEquals(entries.size(), 1);
+    debugAndWriteEntries(ldifWriter, entries, tn);
+
+    // check the DEL entry has the right content
+    SearchResultEntry resultEntry = entries.get(0);
+    checkValue(resultEntry, "replicationcsn", gblCN.toString());
+    // TODO:ECL check values of the other attributes
+
     debugInfo(tn, "Ending test with success");
   }
 
@@ -2897,7 +2742,7 @@
         final StartECLSessionMsg startCLmsg = new StartECLSessionMsg();
         ECLSearchOperation.evaluateSearchParameters(startCLmsg,
             baseDN, SearchFilter.createFilterFromString("(&(changenumber>=2)(changenumber<+5))"));
-        assertTrue(startCLmsg.getFirstDraftChangeNumber()==1);
+        assertEquals(startCLmsg.getFirstDraftChangeNumber(), 1);
       }
       catch (DirectoryException expected)
       {
@@ -2976,15 +2821,12 @@
     // The goal is to verify that the Changelog attributes are not
     // available in other entries. We u
     debugInfo(tn, "Starting test \n\n");
-    {
-      Set<String> attributes = new LinkedHashSet<String>();
-      attributes.add("firstchangenumber");
-      attributes.add("lastchangenumber");
-      attributes.add("changelog");
-      attributes.add("lastExternalChangelogCookie");
 
-      debugInfo(tn, " Search: "+ TEST_ROOT_DN_STRING);
-      InternalSearchOperation searchOp =
+    Set<String> attributes = newSet("firstchangenumber", "lastchangenumber",
+        "changelog", "lastExternalChangelogCookie");
+
+    debugInfo(tn, " Search: " + TEST_ROOT_DN_STRING);
+    InternalSearchOperation searchOp =
         connection.processSearch(
             ByteString.valueOf(TEST_ROOT_DN_STRING),
             SearchScope.BASE_OBJECT,
@@ -2996,22 +2838,21 @@
             attributes,
             NO_CONTROL,
             null);
-      waitOpResult(searchOp, ResultCode.SUCCESS);
-      assertEquals(searchOp.getSearchEntries().size(), 1);
+    waitOpResult(searchOp, ResultCode.SUCCESS);
+    assertEquals(searchOp.getSearchEntries().size(), 1);
 
-      List<SearchResultEntry> entries = searchOp.getSearchEntries();
-      assertEquals(entries.size(), 1);
-      for (SearchResultEntry resultEntry : entries)
-      {
-        debugInfo(tn, "Result entry returned:" + resultEntry.toLDIFString());
-        assertEquals(getAttributeValue(resultEntry, "firstchangenumber"), null);
-        assertEquals(getAttributeValue(resultEntry, "lastchangenumber"), null);
-        assertEquals(getAttributeValue(resultEntry, "changelog"), null);
-        assertEquals(getAttributeValue(resultEntry, "lastExternalChangelogCookie"), null);
-      }
-
-      debugInfo(tn, "Ending test with success");
+    List<SearchResultEntry> entries = searchOp.getSearchEntries();
+    assertEquals(entries.size(), 1);
+    debugAndWriteEntries(null, entries, tn);
+    for (SearchResultEntry resultEntry : entries)
+    {
+      assertEquals(getAttributeValue(resultEntry, "firstchangenumber"), null);
+      assertEquals(getAttributeValue(resultEntry, "lastchangenumber"), null);
+      assertEquals(getAttributeValue(resultEntry, "changelog"), null);
+      assertEquals(getAttributeValue(resultEntry, "lastExternalChangelogCookie"), null);
     }
+
+    debugInfo(tn, "Ending test with success");
   }
 
   private void ECLCompatTestLimits(int expectedFirst, int expectedLast,
@@ -3033,29 +2874,24 @@
       debugInfo(tn, " Search: rootDSE");
       InternalSearchOperation searchOp = searchOnRootDSE(attributes);
       List<SearchResultEntry> entries = searchOp.getSearchEntries();
-      assertEquals(searchOp.getSearchEntries().size(), 1);
-      if (entries != null)
+      assertEquals(entries.size(), 1);
+      SearchResultEntry resultEntry = entries.get(0);
+      debugAndWriteEntries(ldifWriter, entries, tn);
+
+      if (eclEnabled)
       {
-        for (SearchResultEntry resultEntry : entries)
-        {
-          debugInfo(tn, "Result entry returned:" + resultEntry.toLDIFString());
-          ldifWriter.writeEntry(resultEntry);
-          if (eclEnabled)
-          {
-            if (expectedFirst>0)
-              checkValue(resultEntry,"firstchangenumber", String.valueOf(expectedFirst));
-            checkValue(resultEntry,"lastchangenumber", String.valueOf(expectedLast));
-            checkValue(resultEntry,"changelog", String.valueOf("cn=changelog"));
-          }
-          else
-          {
-            if (expectedFirst>0)
-              assertEquals(getAttributeValue(resultEntry, "firstchangenumber"), null);
-            assertEquals(getAttributeValue(resultEntry, "lastchangenumber"), null);
-            assertEquals(getAttributeValue(resultEntry, "changelog"), null);
-            assertEquals(getAttributeValue(resultEntry, "lastExternalChangelogCookie"), null);
-          }
-        }
+        if (expectedFirst > 0)
+          checkValue(resultEntry, "firstchangenumber", String.valueOf(expectedFirst));
+        checkValue(resultEntry, "lastchangenumber", String.valueOf(expectedLast));
+        checkValue(resultEntry, "changelog", String.valueOf("cn=changelog"));
+      }
+      else
+      {
+        if (expectedFirst > 0)
+          assertEquals(getAttributeValue(resultEntry, "firstchangenumber"), null);
+        assertEquals(getAttributeValue(resultEntry, "lastchangenumber"), null);
+        assertEquals(getAttributeValue(resultEntry, "changelog"), null);
+        assertEquals(getAttributeValue(resultEntry, "lastExternalChangelogCookie"), null);
       }
     }
     debugInfo(tn, "Ending test with success");
@@ -3084,29 +2920,27 @@
   {
     String tn = "ECLCompatTestLimitsAndAdd";
     debugInfo(tn, "Starting test\n\n");
-    {
-      ECLCompatTestLimits(expectedFirst, expectedLast, true);
 
-      // Creates broker on o=test
-      ReplicationBroker server01 = openReplicationSession(
-          DN.decode(TEST_ROOT_DN_STRING),  1201,
-          100, replicationServerPort,
-          brokerSessionTimeout, true);
+    ECLCompatTestLimits(expectedFirst, expectedLast, true);
 
-      String user1entryUUID = "11111111-1112-1113-1114-111111111115";
+    // Creates broker on o=test
+    ReplicationBroker server01 =
+        openReplicationSession(DN.decode(TEST_ROOT_DN_STRING), 1201, 100,
+            replicationServerPort, brokerSessionTimeout, true);
 
-      // Publish DEL
-      ChangeNumber cn1 = new ChangeNumber(TimeThread.getTime(), ts++, 1201);
-      DeleteMsg delMsg =
-        new DeleteMsg("uid="+tn+"1," + TEST_ROOT_DN_STRING, cn1,
-            user1entryUUID);
-      server01.publish(delMsg);
-      debugInfo(tn, " publishes " + delMsg.getChangeNumber());
-      sleep(500);
-      server01.stop();
+    String user1entryUUID = "11111111-1112-1113-1114-111111111115";
 
-      ECLCompatTestLimits(expectedFirst, expectedLast+1, true);
-    }
+    // Publish DEL
+    ChangeNumber cn1 = new ChangeNumber(TimeThread.getTime(), ts++, 1201);
+    DeleteMsg delMsg = new DeleteMsg("uid=" + tn + "1," + TEST_ROOT_DN_STRING,
+        cn1, user1entryUUID);
+    server01.publish(delMsg);
+    debugInfo(tn, " publishes " + delMsg.getChangeNumber());
+    sleep(500);
+    server01.stop();
+
+    ECLCompatTestLimits(expectedFirst, expectedLast + 1, true);
+
     debugInfo(tn, "Ending test with success");
   }
 
@@ -3115,14 +2949,13 @@
     String tn = "ECLGetEligibleCountTest";
     debugInfo(tn, "Starting test\n\n");
     String user1entryUUID = "11111111-1112-1113-1114-111111111115";
+    ChangeNumber[] cns = generateChangeNumbers(4, 1201);
     {
       ReplicationServerDomain rsdtest =
         replicationServer.getReplicationServerDomain(TEST_ROOT_DN_STRING, false);
 
       // The replication changelog is empty
-      long count = rsdtest.getEligibleCount(
-          new ServerState(),
-          new ChangeNumber(TimeThread.getTime(), 1, 1201));
+      long count = rsdtest.getEligibleCount(new ServerState(), cns[0]);
       assertEquals(count, 0);
 
       // Creates broker on o=test
@@ -3132,7 +2965,7 @@
           brokerSessionTimeout, true);
 
       // Publish one first message
-      ChangeNumber cn1 = new ChangeNumber(TimeThread.getTime(), 1, 1201);
+      ChangeNumber cn1 = cns[0];
       DeleteMsg delMsg =
         new DeleteMsg("uid="+tn+"1," + TEST_ROOT_DN_STRING, cn1,
             user1entryUUID);
@@ -3141,24 +2974,19 @@
       sleep(300);
 
       // From begin to now : 1 change
-      count = rsdtest.getEligibleCount(
-          new ServerState(),
-          new ChangeNumber(TimeThread.getTime(), 1, 1201));
+      count = rsdtest.getEligibleCount(new ServerState(), cns[0]);
       assertEquals(count, 1);
 
       // Publish one second message
-      ChangeNumber cn2 = new ChangeNumber(TimeThread.getTime(), 2, 1201);
-      delMsg =
-        new DeleteMsg("uid="+tn+"1," + TEST_ROOT_DN_STRING, cn2,
+      ChangeNumber cn2 = cns[1];
+      delMsg = new DeleteMsg("uid=" + tn + "1," + TEST_ROOT_DN_STRING, cn2,
             user1entryUUID);
       server01.publish(delMsg);
       debugInfo(tn, " publishes " + delMsg.getChangeNumber());
       sleep(300);
 
       // From begin to now : 2 changes
-      count = rsdtest.getEligibleCount(
-          new ServerState(),
-          new ChangeNumber(TimeThread.getTime(), 1, 1201));
+      count = rsdtest.getEligibleCount(new ServerState(), cns[0]);
       assertEquals(count, 2);
 
       // From begin to first change (inclusive) : 1 change = cn1
@@ -3179,14 +3007,12 @@
       ss.update(cn2);
 
       // From state/cn2(exclusive) to now (inclusive) : 0 change
-      count = rsdtest.getEligibleCount(ss,
-          new ChangeNumber(TimeThread.getTime(), 4, 1201));
+      count = rsdtest.getEligibleCount(ss, cns[3]);
       assertEquals(count, 0);
 
       // Publish one third message
-      ChangeNumber cn3 = new ChangeNumber(TimeThread.getTime(), 3, 1201);
-      delMsg =
-        new DeleteMsg("uid="+tn+"1," + TEST_ROOT_DN_STRING, cn3,
+      ChangeNumber cn3 = cns[2];
+      delMsg = new DeleteMsg("uid="+tn+"1," + TEST_ROOT_DN_STRING, cn3,
             user1entryUUID);
       server01.publish(delMsg);
       debugInfo(tn, " publishes " + delMsg.getChangeNumber());
@@ -3195,8 +3021,7 @@
       ss.update(cn2);
 
       // From state/cn2(exclusive) to now : 1 change = cn3
-      count = rsdtest.getEligibleCount(ss,
-          new ChangeNumber(TimeThread.getTime(), 4, 1201));
+      count = rsdtest.getEligibleCount(ss, cns[3]);
       assertEquals(count, 1);
 
       boolean perfs=false;
@@ -3212,8 +3037,7 @@
       for (int i=4; i<=maxMsg; i++)
       {
         ChangeNumber cnx = new ChangeNumber(TimeThread.getTime(), i, 1201);
-        delMsg =
-          new DeleteMsg("uid="+tn+i+"," + TEST_ROOT_DN_STRING, cnx,
+        delMsg = new DeleteMsg("uid="+tn+i+"," + TEST_ROOT_DN_STRING, cnx,
               user1entryUUID);
         server01.publish(delMsg);
       }
@@ -3251,13 +3075,7 @@
         long t5 = TimeThread.getTime();
         assertEquals(searchOp.getSearchEntries().size(), 3);
         debugInfo(tn, "Perfs - last 3 changes searched in (ms):" + (t5 - t4));
-        if (searchOp.getSearchEntries() != null)
-        {
-          for (SearchResultEntry resultEntry : searchOp.getSearchEntries())
-          {
-            debugInfo(tn, "Result entry returned:" + resultEntry.toLDIFString());
-          }
-        }
+        debugAndWriteEntries(null, searchOp.getSearchEntries(), tn);
       }
       server01.stop();
     }
@@ -3273,7 +3091,6 @@
     debugInfo(tn, "Starting test\n\n");
     Backend backend2 = null;
     Backend backend3 = null;
-    DeleteOperation delOp = null;
     LDAPReplicationDomain domain2 = null;
     LDAPReplicationDomain domain3 = null;
     LDAPReplicationDomain domain21 = null;
@@ -3284,62 +3101,35 @@
       // Initialize a second test backend o=test2, in addtion to o=test
       // Configure replication on this backend
       // Add the root entry in the backend
-      backend2 = initializeTestBackend(false,
-          TEST_ROOT_DN_STRING2, TEST_BACKEND_ID2);
+      backend2 = initializeTestBackend(false, TEST_ROOT_DN_STRING2, TEST_BACKEND_ID2);
       baseDn2 = DN.decode(TEST_ROOT_DN_STRING2);
-      SortedSet<String> replServers = new TreeSet<String>();
-      replServers.add("localhost:"+replicationServerPort);
-      DomainFakeCfg domainConf =
-        new DomainFakeCfg(baseDn2, 1702, replServers);
+
+      SortedSet<String> replServers = newSet("localhost:" + replicationServerPort);
 
       // on o=test2,sid=1702 include attrs set to : 'sn'
-      SortedSet<String> eclInclude = new TreeSet<String>();
-      eclInclude.add("sn");
-      eclInclude.add("roomnumber");
-      ExternalChangelogDomainFakeCfg eclCfg =
-        new ExternalChangelogDomainFakeCfg(true, eclInclude, eclInclude);
-      domainConf.setExternalChangelogDomain(eclCfg);
-      // Set a Changetime heartbeat interval low enough (less than default
-      // value that is 1000 ms) for the test to be sure to consider all changes
-      // as eligible.
-      domainConf.setChangetimeHeartbeatInterval(10);
-      domain2 = MultimasterReplication.createNewDomain(domainConf);
+      SortedSet<String> eclInclude = newSet("sn", "roomnumber");
+
+      DomainFakeCfg domainConf = new DomainFakeCfg(baseDn2, 1702, replServers);
+      domain2 = createDomain(domainConf, eclInclude, eclInclude);
       domain2.start();
 
-      backend3 = initializeTestBackend(false,
-          TEST_ROOT_DN_STRING3, TEST_BACKEND_ID3);
+      backend3 = initializeTestBackend(false, TEST_ROOT_DN_STRING3, TEST_BACKEND_ID3);
       baseDn3 = DN.decode(TEST_ROOT_DN_STRING3);
-      domainConf =
-        new DomainFakeCfg(baseDn3, 1703, replServers);
 
       // on o=test3,sid=1703 include attrs set to : 'objectclass'
-      eclInclude = new TreeSet<String>();
-      eclInclude.add("objectclass");
+      eclInclude = newSet("objectclass");
 
-      SortedSet<String> eclIncludeForDeletes = new TreeSet<String>();
-      eclIncludeForDeletes.add("*");
+      SortedSet<String> eclIncludeForDeletes = newSet("*");
 
-      eclCfg = new ExternalChangelogDomainFakeCfg(true, eclInclude, eclIncludeForDeletes);
-      domainConf.setExternalChangelogDomain(eclCfg);
-      // Set a Changetime heartbeat interval low enough (less than default
-      // value that is 1000 ms) for the test to be sure to consider all changes
-      // as eligible.
-      domainConf.setChangetimeHeartbeatInterval(10);
-      domain3 = MultimasterReplication.createNewDomain(domainConf);
+      domainConf = new DomainFakeCfg(baseDn3, 1703, replServers);
+      domain3 = createDomain(domainConf, eclInclude, eclIncludeForDeletes);
       domain3.start();
 
       // on o=test2,sid=1704 include attrs set to : 'cn'
-      domainConf = new DomainFakeCfg(baseDn2, 1704, replServers);
-      eclInclude = new TreeSet<String>();
-      eclInclude.add("cn");
+      eclInclude = newSet("cn");
 
-      eclCfg = new ExternalChangelogDomainFakeCfg(true, eclInclude, eclInclude);
-      domainConf.setExternalChangelogDomain(eclCfg);
-      // Set a Changetime heartbeat interval low enough (less than default
-      // value that is 1000 ms) for the test to be sure to consider all changes
-      // as eligible.
-      domainConf.setChangetimeHeartbeatInterval(10);
-      domain21 = MultimasterReplication.createNewDomain(domainConf);
+      domainConf = new DomainFakeCfg(baseDn2, 1704, replServers);
+      domain21 = createDomain(domainConf, eclInclude, eclInclude);
       domain21.start();
 
       sleep(1000);
@@ -3392,12 +3182,7 @@
       waitOpResult(modDNOp, ResultCode.SUCCESS);
 
       // del robert (o=test3)
-      delOp = new DeleteOperationBasis(connection,
-          InternalClientConnection.nextOperationID(),
-          InternalClientConnection.nextMessageID(), null,
-          DN.decode("cn=Robert Hue2," + TEST_ROOT_DN_STRING3));
-      delOp.run();
-      waitOpResult(delOp, ResultCode.SUCCESS);
+      runDeleteOperation("cn=Robert Hue2," + TEST_ROOT_DN_STRING3);
 
       getEntry(DN.decode("cn=Robert Hue2," + TEST_ROOT_DN_STRING3),5000,false);
 
@@ -3407,84 +3192,57 @@
       String cookie = "";
       InternalSearchOperation searchOp =
           searchOnCookieChangelog("(targetDN=*)", cookie, tn, SUCCESS);
-      List<SearchResultEntry> entries = searchOp.getSearchEntries();
-      assertTrue(entries != null);
+      final List<SearchResultEntry> entries = searchOp.getSearchEntries();
+      assertThat(entries).hasSize(8);
+      debugAndWriteEntries(null, entries, tn);
 
       sleep(2000);
 
-      String s = tn + " entries returned= ";
-      if (entries != null)
+      for (SearchResultEntry resultEntry : entries)
       {
-        for (SearchResultEntry resultEntry : entries)
+        String targetdn = getAttributeValue(resultEntry, "targetdn");
+
+        if (targetdn.endsWith("cn=robert hue,o=test3")
+            || targetdn.endsWith("cn=robert hue2,o=test3"))
         {
-          // Expect
-          debugInfo(tn, "Entry returned =" +  resultEntry.toLDIFString());
-          s += "Entry:" + resultEntry.toLDIFString();
+          Entry targetEntry = parseIncludedAttributes(resultEntry, targetdn);
 
-          String targetdn = getAttributeValue(resultEntry, "targetdn");
+          Set<String> eoc = newSet("person", "inetOrgPerson", "organizationalPerson", "top");
+          checkValues(targetEntry, "objectclass", eoc);
 
-          if (targetdn.endsWith("cn=robert hue,o=test3")
-              || targetdn.endsWith("cn=robert hue2,o=test3"))
+          String changeType = getAttributeValue(resultEntry, "changetype");
+          if ("delete".equals(changeType))
           {
-            Entry targetEntry = parseIncludedAttributes(resultEntry, targetdn);
-
-            Set<String> eoc = new HashSet<String>();
-            eoc.add("person");
-            eoc.add("inetOrgPerson");
-            eoc.add("organizationalPerson");
-            eoc.add("top");
-            checkValues(targetEntry, "objectclass", eoc);
-
-            String changeType = getAttributeValue(resultEntry, "changetype");
-            if ("delete".equals(changeType))
-            {
-              // We are using "*" for deletes so should get back 4 attributes.
-              assertEquals(targetEntry.getAttributes().size(), 4);
-              checkValue(targetEntry, "uid", "robert");
-              checkValue(targetEntry, "cn", "Robert Hue2");
-              checkValue(targetEntry, "telephonenumber", "555555");
-              checkValue(targetEntry, "sn", "Robby");
-            }
-            else
-            {
-              assertEquals(targetEntry.getAttributes().size(), 0);
-            }
+            // We are using "*" for deletes so should get back 4 attributes.
+            assertEquals(targetEntry.getAttributes().size(), 4);
+            checkValue(targetEntry, "uid", "robert");
+            checkValue(targetEntry, "cn", "Robert Hue2");
+            checkValue(targetEntry, "telephonenumber", "555555");
+            checkValue(targetEntry, "sn", "Robby");
           }
-          if (targetdn.endsWith("cn=fiona jensen,o=test2"))
+          else
           {
-            Entry targetEntry = parseIncludedAttributes(resultEntry, targetdn);
-
-            assertEquals(targetEntry.getAttributes().size(), 2);
-            checkValue(targetEntry,"sn","jensen");
-            checkValue(targetEntry,"cn","Fiona Jensen");
+            assertEquals(targetEntry.getAttributes().size(), 0);
           }
-          checkValue(resultEntry,"changeinitiatorsname", "cn=Internal Client,cn=Root DNs,cn=config");
         }
+        if (targetdn.endsWith("cn=fiona jensen,o=test2"))
+        {
+          Entry targetEntry = parseIncludedAttributes(resultEntry, targetdn);
+
+          assertEquals(targetEntry.getAttributes().size(), 2);
+          checkValue(targetEntry,"sn","jensen");
+          checkValue(targetEntry,"cn","Fiona Jensen");
+        }
+        checkValue(resultEntry,"changeinitiatorsname", "cn=Internal Client,cn=Root DNs,cn=config");
       }
-      assertEquals(entries.size(),8, "Entries number returned by search" + s);
     }
     finally
     {
       try
       {
-        delOp = new DeleteOperationBasis(connection,
-            InternalClientConnection.nextOperationID(),
-            InternalClientConnection.nextMessageID(), null,
-            DN.decode("cn=Fiona Jensen," + TEST_ROOT_DN_STRING2));
-        delOp.run();
-        waitOpResult(delOp, ResultCode.SUCCESS);
-        delOp = new DeleteOperationBasis(connection,
-            InternalClientConnection.nextOperationID(),
-            InternalClientConnection.nextMessageID(), null,
-            DN.decode(TEST_ROOT_DN_STRING2));
-        delOp.run();
-        waitOpResult(delOp, ResultCode.SUCCESS);
-        delOp = new DeleteOperationBasis(connection,
-            InternalClientConnection.nextOperationID(),
-            InternalClientConnection.nextMessageID(), null,
-            DN.decode(TEST_ROOT_DN_STRING3));
-        delOp.run();
-        waitOpResult(delOp, ResultCode.SUCCESS);
+        runDeleteOperation("cn=Fiona Jensen," + TEST_ROOT_DN_STRING2);
+        runDeleteOperation(TEST_ROOT_DN_STRING2);
+        runDeleteOperation(TEST_ROOT_DN_STRING3);
 
         // Cleaning
         if (domain21 != null)
@@ -3512,6 +3270,23 @@
     debugInfo(tn, "Ending test with success");
   }
 
+  private SortedSet<String> newSet(String... values)
+  {
+    return new TreeSet<String>(Arrays.asList(values));
+  }
+
+  private LDAPReplicationDomain createDomain(DomainFakeCfg domainConf,
+      SortedSet<String> eclInclude, SortedSet<String> eclIncludeForDeletes)
+      throws Exception
+  {
+    domainConf.setExternalChangelogDomain(
+        new ExternalChangelogDomainFakeCfg(true, eclInclude, eclIncludeForDeletes));
+    // Set a Changetime heartbeat interval low enough (less than default value
+    // that is 1000 ms) for the test to be sure to consider all changes as eligible.
+    domainConf.setChangetimeHeartbeatInterval(10);
+    return MultimasterReplication.createNewDomain(domainConf);
+  }
+
   private void runModifyOperation(Entry entry, List<Modification> mods)
       throws Exception
   {
@@ -3521,6 +3296,16 @@
     waitOpResult(operation, ResultCode.SUCCESS);
   }
 
+  private void runDeleteOperation(String dn) throws Exception
+  {
+    final DeleteOperation delOp = new DeleteOperationBasis(connection,
+        InternalClientConnection.nextOperationID(),
+        InternalClientConnection.nextMessageID(), null,
+        DN.decode(dn));
+    delOp.run();
+    waitOpResult(delOp, ResultCode.SUCCESS);
+  }
+
   private List<Modification> createMods(String attributeName, String valueString)
   {
     Attribute attr = Attributes.create(attributeName, valueString);

--
Gitblit v1.10.0