From a2a74542282fa2eba683661058786625b50c6dc7 Mon Sep 17 00:00:00 2001
From: Valery Kharseko <vharseko@3a-systems.ru>
Date: Thu, 24 Sep 2026 06:37:59 +0000
Subject: [PATCH] [#1048] Hold the session restart a released change asks for while a total update runs (#1049)
---
opendj-server-legacy/src/test/java/org/opends/server/replication/plugin/ReplayDuringImportTest.java | 105 ----------------------------------------------------
1 files changed, 0 insertions(+), 105 deletions(-)
diff --git a/opendj-server-legacy/src/test/java/org/opends/server/replication/plugin/ReplayDuringImportTest.java b/opendj-server-legacy/src/test/java/org/opends/server/replication/plugin/ReplayDuringImportTest.java
index 538c7e1..e921beb 100644
--- a/opendj-server-legacy/src/test/java/org/opends/server/replication/plugin/ReplayDuringImportTest.java
+++ b/opendj-server-legacy/src/test/java/org/opends/server/replication/plugin/ReplayDuringImportTest.java
@@ -831,111 +831,6 @@
}
/**
- * A session restart decided while a total update out of this replica is running stops the
- * session that export streams over (issue #1041).
- * <p>
- * What the restart must leave alone is a total update into this replica: the data it is
- * about to replace is read over the session, and the import is the thread the stop waits
- * for. An export is not that: it streams out of a backend nothing is taking away, on a
- * thread of its own, and a session stopped under it is the cut it reports to whoever asked
- * for the total update - the same cut every other stop of the session is. The claim the
- * restart makes for the import is not made here, and the session is stopped as it was
- * before the claim.
- * <p>
- * The export holds the context by standing where it waits for its target to report the
- * start of the total update: the target is a broker of this test, and reports nothing.
- */
- @Test(timeOut = 120_000)
- public void aRestartDecidedWhileAnExportRunsStopsTheSessionItStreamsOver() throws Exception
- {
- final Entry entry = TestCaseUtils.addEntry(
- "dn: cn=renamedSince," + EXAMPLE_DN,
- "objectClass: top",
- "objectClass: person",
- "cn: renamedSince",
- "sn: renamedSince");
- final String entryUUID = getEntryUUID(entry.getName());
- waitUntil(() -> domain.getReplicaInfos().containsKey(EXPORTER_ID),
- "the exporter is not in the replicas of the domain: nothing to export into");
-
- final AtomicReference<Throwable> exportFailure = new AtomicReference<>();
- final Thread export = new Thread(() -> {
- try
- {
- domain.initializeRemote(EXPORTER_ID, null);
- }
- catch (Throwable t)
- {
- exportFailure.set(t);
- }
- }, "export of " + EXAMPLE_DN);
-
- // The restart is held after its decision, before the stop: what the case reads is the
- // decision the export was found by, not the session which is down a moment later.
- final CountDownLatch stopHeld = new CountDownLatch(1);
- final CountDownLatch releaseStop = new CountDownLatch(1);
- domain.setServiceStopHook(() -> {
- stopHeld.countDown();
- awaitUninterruptibly(releaseStop);
- });
- final CSN csn = gen.newCSN();
- final AtomicReference<Throwable> replayFailure = new AtomicReference<>();
- final Thread replay = new Thread(() -> {
- try
- {
- replayMsg(new ModifyMsg(csn, DN.valueOf("cn=movedAway," + EXAMPLE_DN),
- generatemods("description", "replayed while the export was running"), entryUUID));
- }
- catch (Throwable t)
- {
- replayFailure.set(t);
- }
- }, "replay of " + csn);
- try
- {
- export.start();
- waitUntil(() -> domain.ieRunning() || exportFailure.get() != null,
- "the export did not claim the import context");
- assertNull(exportFailure.get(),
- "the export failed before it claimed the context: " + exportFailure.get());
-
- // A change whose entryUUID search never runs spends its attempts in place and asks
- // for the session to be restarted, the way it does in the case above.
- ShortCircuitPlugin.registerShortCircuit(
- OperationType.SEARCH, "PreParse", ResultCode.UNAVAILABLE.intValue());
- try
- {
- replay.start();
- assertTrue(stopHeld.await(30, TimeUnit.SECONDS),
- "the restart left the session to the export: an export is not the owner a total"
- + " update into this replica is");
- }
- finally
- {
- ShortCircuitPlugin.deregisterShortCircuit(OperationType.SEARCH, "PreParse");
- }
- assertTrue(domain.ieRunning(), "the export ended before the restart was decided");
- }
- finally
- {
- releaseStop.countDown();
- domain.setServiceStopHook(null);
- }
-
- replay.join(60_000);
- assertFalse(replay.isAlive(), "the restart did not end");
- assertNull(replayFailure.get(), "the replay failed: " + replayFailure.get());
- export.join(60_000);
- assertFalse(export.isAlive(), "the export did not end once the session it streams over"
- + " was stopped");
- assertThat(exportFailure.get())
- .as("the export was not told that the session it streams over was cut")
- .isInstanceOf(DirectoryException.class);
- waitUntil(domain::isConnected, "the session was not started back after the restart");
- assertFalse(domain.ieRunning(), "the export which was cut left its context claimed");
- }
-
- /**
* Has the exporter start a total update into this replica, and returns once the backend
* of the domain is deregistered for it: from then on the import is reading the session,
* and a change replayed here is replayed into no backend.
--
Gitblit v1.10.0