From f872566aafe7dd516fd50b5cb8ce6b3002746e71 Mon Sep 17 00:00:00 2001
From: Valery Kharseko <vharseko@3a-systems.ru>
Date: Wed, 08 Jul 2026 16:12:28 +0000
Subject: [PATCH] Fix and enable broken tests from the slow group (#686)

---
 opendj-server-legacy/src/test/java/org/opends/server/replication/plugin/TopologyViewTest.java |  111 +++++++++++++++++++++---------------
 opendj-server-legacy/src/test/java/org/opends/server/replication/UpdateOperationTest.java     |   36 ++++++++++-
 opendj-server-legacy/src/test/java/org/opends/server/tasks/TestRebuildTask.java               |    7 +-
 3 files changed, 98 insertions(+), 56 deletions(-)

diff --git a/opendj-server-legacy/src/test/java/org/opends/server/replication/UpdateOperationTest.java b/opendj-server-legacy/src/test/java/org/opends/server/replication/UpdateOperationTest.java
index 34900cc..d973d2d 100644
--- a/opendj-server-legacy/src/test/java/org/opends/server/replication/UpdateOperationTest.java
+++ b/opendj-server-legacy/src/test/java/org/opends/server/replication/UpdateOperationTest.java
@@ -13,6 +13,7 @@
  *
  * Copyright 2006-2010 Sun Microsystems, Inc.
  * Portions Copyright 2011-2016 ForgeRock AS.
+ * Portions Copyright 2023-2026 3A Systems, LLC
  */
 package org.opends.server.replication;
 
@@ -357,7 +358,7 @@
    * Tests whether the synchronization provider fails over when it loses
    * the heartbeat from the replication server.
    */
-  @Test(groups = "slow")
+  @Test
   public void lostHeartbeatFailover() throws Exception
   {
     testSetUp("lostHeartbeatFailover");
@@ -428,7 +429,7 @@
    * It then uses this session to simulate conflicts and therefore
    * test the modify conflict resolution code.
    */
-  @Test(enabled=true, groups="slow")
+  @Test(enabled=true)
   public void modifyConflicts() throws Exception
   {
     testSetUp("modifyConflicts");
@@ -532,7 +533,7 @@
       attrs = entry.getAllAttributes(attrType);
 
       // there should not be a value (delete at time t2)
-      assertNull(attrs);
+      Assertions.assertThat(attrs).isEmpty();
       assertEquals(getMonitorDelta(), 1);
     }
     finally
@@ -542,6 +543,28 @@
   }
 
   /**
+   * Waits for the replay thread to update the monitored counter: reading the
+   * monitor immediately after publishing a message races with the replay.
+   */
+  private void waitForMonitorDelta(final long expectedDelta) throws Exception
+  {
+    final long[] total = { 0 };
+    TestTimer timer = new TestTimer.Builder()
+      .maxSleep(30, SECONDS)
+      .sleepTimes(100, MILLISECONDS)
+      .toTimer();
+    timer.repeatUntilSuccess(new CallableVoid()
+    {
+      @Override
+      public void call() throws Exception
+      {
+        total[0] += getMonitorDelta();
+        assertEquals(total[0], expectedDelta);
+      }
+    });
+  }
+
+  /**
    * Tests the naming conflict resolution code.
    * In this test, the local server act both as an LDAP server and
    * a replicationServer that are inter-connected.
@@ -551,7 +574,7 @@
    * It then uses this session to simulate conflicts and therefore
    * test the naming conflict resolution code.
    */
-  @Test(enabled=true, groups="slow")
+  @Test(enabled=true)
   public void namingConflicts() throws Exception
   {
     testSetUp("namingConflicts");
@@ -750,7 +773,10 @@
       // check that the delete operation has not been applied
       assertNotNull(getEntry(newPersonDN, 10000, true),
           "The DELETE replication message was replayed when it should not");
-      assertEquals(getMonitorDelta(), 1);
+      // The entry already exists, so the getEntry() call above does not wait
+      // for the replay: poll the monitor until the replay thread has resolved
+      // the conflict.
+      waitForMonitorDelta(1);
       assertConflictAutomaticallyResolved(alertCount);
 
 
diff --git a/opendj-server-legacy/src/test/java/org/opends/server/replication/plugin/TopologyViewTest.java b/opendj-server-legacy/src/test/java/org/opends/server/replication/plugin/TopologyViewTest.java
index baab6a7..0c9ff62 100644
--- a/opendj-server-legacy/src/test/java/org/opends/server/replication/plugin/TopologyViewTest.java
+++ b/opendj-server-legacy/src/test/java/org/opends/server/replication/plugin/TopologyViewTest.java
@@ -13,9 +13,12 @@
  *
  * Copyright 2008-2010 Sun Microsystems, Inc.
  * Portions Copyright 2011-2016 ForgeRock AS.
+ * Portions Copyright 2026 3A Systems, LLC
  */
 package org.opends.server.replication.plugin;
 
+import static java.util.concurrent.TimeUnit.*;
+
 import static org.opends.server.TestCaseUtils.*;
 import static org.testng.Assert.*;
 
@@ -42,6 +45,8 @@
 import org.opends.server.replication.protocol.ProtocolVersion;
 import org.opends.server.replication.server.ReplServerFakeConfiguration;
 import org.opends.server.replication.server.ReplicationServer;
+import org.opends.server.util.TestTimer;
+import org.opends.server.util.TestTimer.CallableVoid;
 import org.testng.annotations.Test;
 
 /**
@@ -469,7 +474,7 @@
    * in DS1,DS2,DS5,DS6)
    * @throws Exception If a problem occurred
    */
-  @Test(enabled = true, groups = "slow")
+  @Test(enabled = true)
   public void testTopologyChanges() throws Exception
   {
     String testCase = "testTopologyChanges";
@@ -929,57 +934,69 @@
    * with the theoretical topology view that every body should have at the time
    * this method is called.
    */
-  private void checkTopoView(int[] dsIdList, TopoView theoricalTopoView)
+  private void checkTopoView(final int[] dsIdList, final TopoView theoricalTopoView)
       throws Exception
   {
-   Thread.sleep(500);
-   for(int currentDsId : dsIdList)
-   {
-     LDAPReplicationDomain rd = null;
+    // Topology messages are propagated asynchronously: poll until every DS
+    // sees the expected view instead of relying on a fixed sleep.
+    TestTimer timer = new TestTimer.Builder()
+      .maxSleep(30, SECONDS)
+      .sleepTimes(100, MILLISECONDS)
+      .toTimer();
+    timer.repeatUntilSuccess(new CallableVoid()
+    {
+      @Override
+      public void call() throws Exception
+      {
+        for (int currentDsId : dsIdList)
+        {
+          LDAPReplicationDomain rd = null;
 
-     switch (currentDsId)
-     {
-       case DS1_ID:
-         rd = rd1;
-         break;
-       case DS2_ID:
-         rd = rd2;
-         break;
-       case DS3_ID:
-         rd = rd3;
-         break;
-       case DS4_ID:
-         rd = rd4;
-         break;
-       case DS5_ID:
-         rd = rd5;
-         break;
-       case DS6_ID:
-         rd = rd6;
-         break;
-       default:
-         fail("Unknown replication domain server id.");
-     }
+          switch (currentDsId)
+          {
+            case DS1_ID:
+              rd = rd1;
+              break;
+            case DS2_ID:
+              rd = rd2;
+              break;
+            case DS3_ID:
+              rd = rd3;
+              break;
+            case DS4_ID:
+              rd = rd4;
+              break;
+            case DS5_ID:
+              rd = rd5;
+              break;
+            case DS6_ID:
+              rd = rd6;
+              break;
+            default:
+              fail("Unknown replication domain server id.");
+          }
 
-     /**
-      * Get the topo view of the current analyzed DS
-      */
-     // Add info for DS itself:
-     // we need to clone the list as we don't want to modify the list kept
-     // inside the DS.
-      final DSInfo dsInfo = new DSInfo(rd.getServerId(), "dummy:1234", rd.getRsServerId(),
-          TEST_DN_WITH_ROOT_ENTRY_GENID,
-          rd.getStatus(),
-          rd.isAssured(), rd.getAssuredMode(), rd.getAssuredSdLevel(),
-          rd.getGroupId(), rd.getRefUrls(),
-          rd.getEclIncludes(), rd.getEclIncludesForDeletes(),
-          ProtocolVersion.getCurrentVersion());
-      final List<DSInfo> dsList = new ArrayList<>(rd.getReplicaInfos().values());
-      dsList.add(dsInfo);
+          /**
+           * Get the topo view of the current analyzed DS
+           */
+          // Add info for DS itself:
+          // we need to clone the list as we don't want to modify the list kept
+          // inside the DS.
+          final DSInfo dsInfo = new DSInfo(rd.getServerId(), "dummy:1234", rd.getRsServerId(),
+              TEST_DN_WITH_ROOT_ENTRY_GENID,
+              rd.getStatus(),
+              rd.isAssured(), rd.getAssuredMode(), rd.getAssuredSdLevel(),
+              rd.getGroupId(), rd.getRefUrls(),
+              rd.getEclIncludes(), rd.getEclIncludesForDeletes(),
+              ProtocolVersion.getCurrentVersion());
+          final List<DSInfo> dsList = new ArrayList<>(rd.getReplicaInfos().values());
+          dsList.add(dsInfo);
 
-     TopoView dsTopoView = new TopoView(dsList, rd.getRsInfos());
-     assertEquals(dsTopoView, theoricalTopoView, " in DSid=" + currentDsId);
-   }
+          TopoView dsTopoView = new TopoView(dsList, rd.getRsInfos());
+          assertEquals(dsTopoView, theoricalTopoView, " in DSid=" + currentDsId);
+        }
+      }
+    });
   }
 
   /**
diff --git a/opendj-server-legacy/src/test/java/org/opends/server/tasks/TestRebuildTask.java b/opendj-server-legacy/src/test/java/org/opends/server/tasks/TestRebuildTask.java
index ae0ba94..beb52bd 100644
--- a/opendj-server-legacy/src/test/java/org/opends/server/tasks/TestRebuildTask.java
+++ b/opendj-server-legacy/src/test/java/org/opends/server/tasks/TestRebuildTask.java
@@ -13,6 +13,7 @@
  *
  * Copyright 2006-2009 Sun Microsystems, Inc.
  * Portions Copyright 2011-2014 ForgeRock AS.
+ * Portions Copyright 2026 3A Systems, LLC
  */
 package org.opends.server.tasks;
 
@@ -106,7 +107,6 @@
                    "ds-task-class-name: org.opends.server.tasks.RebuildTask",
                    "ds-task-rebuild-base-dn: " + suffix,
                    "ds-task-rebuild-index: dn2id",
-                   "ds-task-rebuild-index: dn2uri",
                    "ds-task-rebuild-index: mail"
               ),
               TaskState.COMPLETED_SUCCESSFULLY
@@ -120,15 +120,14 @@
                    "objectclass: ds-task-rebuild",
                    "ds-task-class-name: org.opends.server.tasks.RebuildTask",
                    "ds-task-rebuild-base-dn: ou=bad," + suffix,
-                   "ds-task-rebuild-index: dn2id",
-                   "ds-task-rebuild-index: dn2uri"
+                   "ds-task-rebuild-index: dn2id"
               ),
               TaskState.STOPPED_BY_ERROR
          },
     };
   }
 
-   @Test(dataProvider = "taskentry", groups = "slow")
+   @Test(dataProvider = "taskentry")
   public void testRebuildTask(Entry taskEntry, TaskState expectedState)
        throws Exception
   {

--
Gitblit v1.10.0