From 9300ffec887a766b1ccf27198f69f7e5d5e3fb84 Mon Sep 17 00:00:00 2001
From: Valery Kharseko <vharseko@3a-systems.ru>
Date: Tue, 15 Sep 2026 07:24:43 +0000
Subject: [PATCH] [#956] Tell a failed entryUUID search apart from an entry which is not there (#968)
---
opendj-server-legacy/src/test/java/org/opends/server/plugins/ShortCircuitPlugin.java | 85 +++++++++++++++++++++++++++++++++++++++---
1 files changed, 79 insertions(+), 6 deletions(-)
diff --git a/opendj-server-legacy/src/test/java/org/opends/server/plugins/ShortCircuitPlugin.java b/opendj-server-legacy/src/test/java/org/opends/server/plugins/ShortCircuitPlugin.java
index f61b23d..786fce9 100644
--- a/opendj-server-legacy/src/test/java/org/opends/server/plugins/ShortCircuitPlugin.java
+++ b/opendj-server-legacy/src/test/java/org/opends/server/plugins/ShortCircuitPlugin.java
@@ -644,16 +644,18 @@
// Check for registered short circuits.
final String key = keyFor(operation.getOperationType(), section);
Integer resultCode = shortCircuits.get(key);
- if (resultCode != null)
+ if (resultCode != null && appliesTo(key, operation))
{
final int reached = shortCircuitCounts.computeIfAbsent(key, k -> new AtomicInteger()).incrementAndGet();
+ final int letThroughFirst = shortCircuitSkips.getOrDefault(key, 0);
final Integer maxTimes = shortCircuitLimits.get(key);
- if (maxTimes == null || reached <= maxTimes)
+ if (reached > letThroughFirst && (maxTimes == null || reached <= letThroughFirst + maxTimes))
{
return resultCode;
}
- // The short circuit was applied as many times as it was asked for: from now on the
- // operations are let through, which is how a transient failure is simulated.
+ // The operations before the short circuit are let through, and so are the ones after
+ // it was applied as many times as it was asked for: this is how a transient failure
+ // which starts, or ends, part way through a sequence of operations is simulated.
}
/*
@@ -740,6 +742,23 @@
/** How many times a registered short circuit must be applied, when it is limited. */
private static final Map<String, Integer> shortCircuitLimits = new ConcurrentHashMap<>();
+ /** How many operations a registered short circuit lets through before it applies. */
+ private static final Map<String, Integer> shortCircuitSkips = new ConcurrentHashMap<>();
+
+ /**
+ * Which operations a registered short circuit is for, when it is not for every operation
+ * of its type: the ones it is not for are neither short circuited nor counted.
+ */
+ private static final Map<String, Predicate<PluginOperation>> shortCircuitFilters =
+ new ConcurrentHashMap<>();
+
+ /** Returns whether the short circuit registered under the given key is for the given operation. */
+ private static boolean appliesTo(String key, PluginOperation operation)
+ {
+ final Predicate<PluginOperation> filter = shortCircuitFilters.get(key);
+ return filter == null || filter.test(operation);
+ }
+
/**
* Returns how many times the short circuit registered for the given operation type and
* plugin point was reached. A short circuit registered for a limited number of times is
@@ -765,10 +784,13 @@
public static void registerShortCircuit(OperationType operation, String section, int resultCode)
{
final String key = keyFor(operation, section);
- // This registration applies to every operation, and it counts from zero: a limit or
- // a count left behind by a previous registration is not part of it.
+ // This registration applies to every operation, and it counts from zero: a limit, a
+ // number of operations let through or a count left behind by a previous registration
+ // is not part of it.
shortCircuitCounts.remove(key);
shortCircuitLimits.remove(key);
+ shortCircuitSkips.remove(key);
+ shortCircuitFilters.remove(key);
shortCircuits.put(key, resultCode);
}
@@ -783,13 +805,62 @@
*/
public static void registerShortCircuit(OperationType operation, String section, int resultCode, int maxTimes)
{
+ registerShortCircuit(operation, section, resultCode, 0, maxTimes);
+ }
+
+ /**
+ * Register a short circuit which lets the given number of operations through before it
+ * applies, then applies to the given number of operations, the ones which follow being
+ * let through again: this is how a transient failure which starts part way through a
+ * sequence of operations is simulated - the second search of an attempt failing while
+ * the first one ran, say.
+ *
+ * @param operation The type of operation the short circuit applies to.
+ * @param section The plugin point the short circuit applies to.
+ * @param resultCode The result code to be returned for the short circuit.
+ * @param letThroughFirst How many operations must be let through before the short
+ * circuit applies.
+ * @param maxTimes How many operations must be short circuited after them.
+ */
+ public static void registerShortCircuit(OperationType operation, String section, int resultCode,
+ int letThroughFirst, int maxTimes)
+ {
final String key = keyFor(operation, section);
shortCircuitCounts.remove(key);
+ shortCircuitFilters.remove(key);
+ shortCircuitSkips.put(key, letThroughFirst);
shortCircuitLimits.put(key, maxTimes);
shortCircuits.put(key, resultCode);
}
/**
+ * Register a short circuit like
+ * {@link #registerShortCircuit(OperationType, String, int, int, int)}, for some of the
+ * operations of the given type only: the ones the predicate does not accept are let
+ * through without being counted, as if the short circuit were not there.
+ * <p>
+ * The operations of one type which reach a plugin point are not all the test's: the
+ * server makes internal operations of its own on its own schedule - the ServerState flush
+ * thread of a replication domain writes the base entry with a Modify on its tick, say -
+ * and a short circuit which counts them takes a let-through, or a refusal, meant for the
+ * operation the test is driving. A test which counts its operations one by one names them.
+ *
+ * @param operation The type of operation the short circuit applies to.
+ * @param section The plugin point the short circuit applies to.
+ * @param resultCode The result code to be returned for the short circuit.
+ * @param letThroughFirst How many of the operations the predicate accepts must be let
+ * through before the short circuit applies.
+ * @param maxTimes How many of them must be short circuited after those.
+ * @param appliesTo Which operations of that type the short circuit is for.
+ */
+ public static void registerShortCircuit(OperationType operation, String section, int resultCode,
+ int letThroughFirst, int maxTimes, Predicate<PluginOperation> appliesTo)
+ {
+ registerShortCircuit(operation, section, resultCode, letThroughFirst, maxTimes);
+ shortCircuitFilters.put(keyFor(operation, section), appliesTo);
+ }
+
+ /**
* Deregister a short circuit for the given operation type and plugin point.
* @param operation The type of operation the short circuit applies to.
* @param section The plugin point the short circuit applies to.
@@ -799,6 +870,8 @@
final String key = keyFor(operation, section);
shortCircuits.remove(key);
shortCircuitLimits.remove(key);
+ shortCircuitSkips.remove(key);
+ shortCircuitFilters.remove(key);
// The count belongs to the registration which is being removed: a test which counts
// the operations it short circuits must not inherit the count of the previous one.
shortCircuitCounts.remove(key);
--
Gitblit v1.10.0