package org.infinispan.counter; import static org.testng.AssertJUnit.assertEquals; import static org.testng.AssertJUnit.assertFalse; import static org.testng.AssertJUnit.assertTrue; import static org.testng.AssertJUnit.fail; import java.lang.reflect.Method; import java.util.concurrent.ExecutionException; import org.infinispan.counter.api.CounterConfiguration; import org.infinispan.counter.api.CounterManager; import org.infinispan.counter.api.CounterType; import org.infinispan.counter.exception.CounterOutOfBoundsException; import org.infinispan.counter.util.StrongTestCounter; import org.testng.annotations.Test; /** * A simple counter notification test for bounded {@link org.infinispan.counter.impl.entries.CounterValue}. * * @author Pedro Ruivo * @since 9.0 */ @Test(groups = "functional", testName = "counter.BoundedCounterTest") public class BoundedCounterTest extends StrongCounterTest { private void assertOutOfBoundsAdd(StrongTestCounter counter, long delta, long expected) { try { counter.add(delta); fail("Bound should have been reached!"); } catch (CounterOutOfBoundsException e) { log.debug("Expected exception.", e); } assertEquals("Wrong return value of counter.getNewValue()", expected, counter.getValue()); } public void testSimpleThreshold(Method method) throws ExecutionException, InterruptedException { CounterManager counterManager = counterManager(0); counterManager.defineCounter(method.getName(), CounterConfiguration.builder(CounterType.BOUNDED_STRONG).lowerBound(-1).upperBound(1).build()); StrongTestCounter counter = new StrongTestCounter(counterManager.getStrongCounter(method.getName())); addAndAssertResult(counter, 1, 1); assertOutOfBoundsAdd(counter, 1, 1); addAndAssertResult(counter, -1, 0); addAndAssertResult(counter, -1, -1); assertOutOfBoundsAdd(counter, -1, -1); counter.reset(); assertOutOfBoundsAdd(counter, 2, 1); assertOutOfBoundsAdd(counter, -3, -1); } public void testCompareAndSetBounds(Method method) { CounterManager counterManager = counterManager(0); counterManager.defineCounter(method.getName(), CounterConfiguration.builder(CounterType.BOUNDED_STRONG).lowerBound(-2).upperBound(2).build()); SyncStrongCounter counter = new SyncStrongCounter(counterManager.getStrongCounter(method.getName())); assertTrue(counter.compareAndSet(0, 2)); assertEquals(2, counter.getValue()); assertOutOfBoundCas(counter, 2, 3); counter.reset(); assertTrue(counter.compareAndSet(0, -2)); assertEquals(-2, counter.getValue()); assertOutOfBoundCas(counter, -2, -3); counter.reset(); assertFalse(counter.compareAndSet(1, 3)); assertFalse(counter.compareAndSet(1, -3)); } private void assertOutOfBoundCas(SyncStrongCounter counter, long expect, long value) { try { counter.compareAndSet(expect, value); fail("Threshold should have been reached!"); } catch (CounterOutOfBoundsException e) { log.debug("Expected exception", e); } assertEquals("Wrong return value of counter.getNewValue()", expect, counter.getValue()); } @Override protected StrongTestCounter createCounter(CounterManager counterManager, String counterName, long initialValue) { counterManager.defineCounter(counterName, CounterConfiguration.builder(CounterType.BOUNDED_STRONG).lowerBound(Long.MIN_VALUE) .upperBound(Long.MAX_VALUE).initialValue(initialValue).build()); return new StrongTestCounter(counterManager.getStrongCounter(counterName)); } @Override protected void assertMaxValueAfterMaxValue(StrongTestCounter counter, long delta) { assertOutOfBoundsAdd(counter, delta, Long.MAX_VALUE); } @Override protected void assertMinValueAfterMinValue(StrongTestCounter counter, long delta) { assertOutOfBoundsAdd(counter, delta, Long.MIN_VALUE); } }