All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.mats3.test.MatsTestBarrier Maven / Gradle / Ivy

package io.mats3.test;

/**
 * Test-utility: Simple barrier-functionality facilitating communication back from some async processing to the main
 * thread that sent a message to some processor, and is now waiting for the async processing to complete.
 * 

* Can be used to wait for a result, or for an exception to be thrown. If the opposite of what you're waiting for is * what is resolved (i.e. you're waiting for a result, but an exception is thrown), an {@link AssertionError} is raised. * * @see MatsTestLatch * @author Endre Stølsvik 2024-10-13 02:19 - http://stolsvik.com/, [email protected] */ public class MatsTestBarrier { private final Object _lock = new Object(); private boolean _resolved = false; private Object _result; private Throwable _exception; /** * Resolves the barrier without result. */ public void resolve() { synchronized (_lock) { if (_resolved) { throw new IllegalStateException("Barrier already resolved."); } _resolved = true; _result = null; _lock.notifyAll(); } } /** * Resolves the barrier, and sets the result. * * @param result * the result of the async processing. */ public void resolve(Object result) { synchronized (_lock) { if (_resolved) { throw new IllegalStateException("Barrier already resolved."); } _resolved = true; _result = result; _lock.notifyAll(); } } /** * Resolves the barrier with an exception. * * @param exception * the exception that occurred during the async processing. */ public void resolveException(Throwable exception) { synchronized (_lock) { if (_resolved) { throw new IllegalStateException("Barrier already resolved."); } _resolved = true; _exception = exception; _lock.notifyAll(); } } /** * Waits for the barrier to be resolved for 30 seconds, returning the result. If the result is already in, it * immediately returns. If the result does not come within timeout, an {@link AssertionError} is raised. */ public T await() { return await(30_000); } /** * Waits for the barrier to be resolved, returning the result. If the result is already in, it immediately returns. * If the result does not come within timeout, an {@link AssertionError} is raised. * * @param timeoutMillis * the max time to wait. * @return the result. Throws {@link AssertionError} if not gotten within timeout. */ public T await(long timeoutMillis) { synchronized (_lock) { if (!_resolved) { try { _lock.wait(timeoutMillis); } catch (InterruptedException e) { throw new AssertionError("Interrupted while waiting for barrier to resolve.", e); } } if (!_resolved) { throw new AssertionError("Barrier was not resolved within timeout [" + timeoutMillis + " ms]."); } if (_exception != null) { throw new AssertionError("Barrier was unexpectedly resolved with exception: " + _exception.getMessage(), _exception); } @SuppressWarnings("unchecked") T ret = (T) _result; return ret; } } /** * Assert that this barrier is NOT resolved - which inherently is problematic since it is an assertion that * something did NOT happen yet! This method will wait for the * {@link MatsTestLatch#WAIT_MILLIS_FOR_NON_OCCURRENCE} milliseconds for the barrier to not resolve, and then raise * an {@link AssertionError} if it did resolve. */ public void awaitNoResult() { synchronized (_lock) { if (!_resolved) { try { _lock.wait(MatsTestLatch.WAIT_MILLIS_FOR_NON_OCCURRENCE); } catch (InterruptedException e) { throw new AssertionError("Interrupted while waiting for barrier to NOT resolve.", e); } } if (_resolved) { throw new AssertionError("Barrier was unexpectedly resolved within timeout [" + MatsTestLatch.WAIT_MILLIS_FOR_NON_OCCURRENCE + " ms] - we expected it to NOT resolve!"); } } } /** * Waits for the barrier to be resolved exceptionally for 30 seconds, returning the exception. If the exception is * already in, it immediately returns. If the exception does not come within timeout, an {@link AssertionError} is * raised. * * @return the exception. Throws {@link AssertionError} if not gotten within timeout. */ public Throwable awaitException() { return awaitException(30_000); } /** * Waits for the barrier to be resolved exceptionally, returning the exception. If the exception is already in, it * immediately returns. If the exception does not come within timeout, an {@link AssertionError} is raised. * * @param timeoutMillis * the max time to wait. * @return the exception. Throws {@link AssertionError} if not gotten within timeout. */ public Throwable awaitException(long timeoutMillis) { synchronized (_lock) { if (!_resolved) { try { _lock.wait(timeoutMillis); } catch (InterruptedException e) { throw new AssertionError("Interrupted while waiting for barrier to resolve.", e); } } if (!_resolved) { throw new AssertionError("Barrier was not resolved within timeout [" + timeoutMillis + " ms]."); } if (_result != null) { throw new AssertionError("Barrier was unexpectedly resolved with result: " + _result); } return _exception; } } /** * Resets the barrier, so that it can be reused. */ public void reset() { synchronized (_lock) { _resolved = false; _result = null; _exception = null; } } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy