From d0422c684b5fc32280ec28813d2ab06a047ee63a Mon Sep 17 00:00:00 2001
From: Valery Kharseko <vharseko@3a-systems.ru>
Date: Wed, 09 Sep 2026 07:02:11 +0000
Subject: [PATCH] [#909] Cover the change a stopped replay thread hands back to the replication server (#941)

---
 opendj-server-legacy/src/test/java/org/opends/server/replication/ReplicationTestCase.java |   55 +++++++++++++++++++++++++++++++++++++++++++++++++++++--
 1 files changed, 53 insertions(+), 2 deletions(-)

diff --git a/opendj-server-legacy/src/test/java/org/opends/server/replication/ReplicationTestCase.java b/opendj-server-legacy/src/test/java/org/opends/server/replication/ReplicationTestCase.java
index a1eeb60..bcedc42 100644
--- a/opendj-server-legacy/src/test/java/org/opends/server/replication/ReplicationTestCase.java
+++ b/opendj-server-legacy/src/test/java/org/opends/server/replication/ReplicationTestCase.java
@@ -102,6 +102,16 @@
   /** Generation id for a fully empty domain. */
   public static final long EMPTY_DN_GENID = GenerationIdChecksum.EMPTY_BACKEND_GENERATION_ID;
 
+  /** The group a replication server and a replication domain are in unless told otherwise. */
+  protected static final int DEFAULT_GROUP_ID = 1;
+
+  /**
+   * The group of a broker which is in none. Assured replication does not cross group ids,
+   * so such a broker is never waited for and never waits: it is all a broker which only
+   * publishes and reads updates needs.
+   */
+  private static final int NO_GROUP_ID = -1;
+
   /** How many times {@link #assertMonitorAttrValueStays} reads a value by default. */
   private static final int MONITOR_ATTR_SAMPLES = 5;
 
@@ -241,7 +251,42 @@
       int serverId, int windowSize, int port, int timeout,
       long generationId) throws Exception
   {
-    final DomainFakeCfg config = newFakeCfg(baseDN, serverId, port);
+    return openReplicationSession(
+        newFakeCfg(baseDN, serverId, port), windowSize, timeout, generationId);
+  }
+
+  /**
+   * Open a session to the local ReplicationServer which takes part in assured replication.
+   * <p>
+   * Assured replication does not cross group ids, so a broker whose updates are to be
+   * acknowledged by the replicas of this server has to be in the group of the replication
+   * server: an update published by a broker of another group is acknowledged on the spot,
+   * by the replication server itself, and says nothing about what any replica did with it.
+   * <p>
+   * The group cuts both ways, and this broker does not acknowledge anything: the
+   * replication server expects an ack from every replica of its group whatever that
+   * replica is configured for, so a SAFE_READ update published by anyone else while this
+   * broker is connected waits out the {@code assured-timeout} of the server. Publish the
+   * assured updates from this broker, and open only one of them.
+   *
+   * @param baseDN the suffix the session is opened for
+   * @param serverId the id this broker takes
+   * @param windowSize the window size of the session
+   * @param port the port of the local replication server
+   * @param timeout the read timeout of the session, or 0 for none
+   * @return the connected broker
+   * @throws Exception if the session could not be opened
+   */
+  protected ReplicationBroker openAssuredReplicationSession(final DN baseDN,
+      int serverId, int windowSize, int port, int timeout) throws Exception
+  {
+    return openReplicationSession(newFakeCfg(baseDN, serverId, port, DEFAULT_GROUP_ID),
+        windowSize, timeout, getGenerationId(baseDN));
+  }
+
+  private ReplicationBroker openReplicationSession(final DomainFakeCfg config,
+      int windowSize, int timeout, long generationId) throws Exception
+  {
     config.setWindowSize(windowSize);
 
     final ReplicationBroker broker = new ReplicationBroker(
@@ -253,7 +298,13 @@
 
   protected DomainFakeCfg newFakeCfg(final DN baseDN, int serverId, int port)
   {
-    DomainFakeCfg fakeCfg = new DomainFakeCfg(baseDN, serverId, newTreeSet("127.0.0.1:" + port));
+    return newFakeCfg(baseDN, serverId, port, NO_GROUP_ID);
+  }
+
+  protected DomainFakeCfg newFakeCfg(final DN baseDN, int serverId, int port, int groupId)
+  {
+    DomainFakeCfg fakeCfg =
+        new DomainFakeCfg(baseDN, serverId, newTreeSet("127.0.0.1:" + port), groupId);
     fakeCfg.setHeartbeatInterval(100000);
     fakeCfg.setChangetimeHeartbeatInterval(500);
     return fakeCfg;

--
Gitblit v1.10.0