public class IdempotenceChecker
extends java.lang.Object
Constructor and Description |
---|
IdempotenceChecker() |
Modifier and Type | Method and Description |
---|---|
static <T> void |
applyForRandomCheck(T data,
java.lang.Object provider,
Computable<? extends T> recomputeValue)
Call this when accessing an already cached value, so that once in a while
(depending on "platform.random.idempotence.check.rate" registry value)
the computation is re-run and checked for consistency with that cached value.
|
static boolean |
areRandomChecksEnabled() |
static <T> void |
checkEquivalence(T existing,
T fresh,
java.lang.Class<?> providerClass,
Computable<? extends T> recomputeValue)
Perform some basic checks whether the two given objects are equivalent and interchangeable,
as described in e.g
CachedValue contract. |
static void |
disableRandomChecksUntil(Disposable parentDisposable)
Useful when your test checks how many times a specific code was called, and random checks make that test flaky.
|
static boolean |
isCurrentThreadInsideRandomCheck() |
static boolean |
isLoggingEnabled() |
static void |
logTrace(java.lang.String message)
Log a message to help debug
checkEquivalence(T, T, java.lang.Class<?>, com.intellij.openapi.util.Computable<? extends T>) failures. |
public static <T> void checkEquivalence(T existing, T fresh, java.lang.Class<?> providerClass, Computable<? extends T> recomputeValue)
CachedValue
contract. This method should be used
in places caching results of various computations, which are expected to be idempotent:
they can be performed several times, or on multiple threads, and the results should be interchangeable.
What to do if you get an error from here:
logTrace(java.lang.String)
.
IdempotenceChecker.checkEquivalence()
for their results as well, localizing the error.Registry.get("platform.random.idempotence.check.rate").setValue(1, getTestRootDisposable())
to perform the idempotence check on every cache access. Note that this can make your test much slower.
ThreadLocal
or method parameters with different values.applyForRandomCheck(T, java.lang.Object, com.intellij.openapi.util.Computable<? extends T>)
: outdated cached value (not all dependencies are specified, or their modification counters aren't properly incremented)existing
- the value computed on the first invocationfresh
- the value computed a bit later, expected to be equivalentproviderClass
- a class of the function performing the computation, used to prevent reporting the same error multiple timesrecomputeValue
- optionally, a way to recalculate the value one more time with isLoggingEnabled()
true,
and include the log collected via logTrace(java.lang.String)
into exception report.public static boolean areRandomChecksEnabled()
applyForRandomCheck(T, java.lang.Object, com.intellij.openapi.util.Computable<? extends T>)
at all.public static void disableRandomChecksUntil(Disposable parentDisposable)
public static <T> void applyForRandomCheck(T data, java.lang.Object provider, Computable<? extends T> recomputeValue)
public static boolean isCurrentThreadInsideRandomCheck()
public static boolean isLoggingEnabled()
logTrace(java.lang.String)
will actually log anythingpublic static void logTrace(java.lang.String message)
checkEquivalence(T, T, java.lang.Class<?>, com.intellij.openapi.util.Computable<? extends T>)
failures. When such a failure occurs, the computation can be re-run again
with this logging enabled, and the collected log will be included into exception message.