package org.infinispan.counter; import static java.lang.String.format; import static org.testng.AssertJUnit.assertEquals; import static org.testng.AssertJUnit.assertFalse; import static org.testng.AssertJUnit.assertTrue; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.HashSet; import java.util.LinkedList; import java.util.List; import java.util.Set; import java.util.concurrent.CyclicBarrier; import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import org.infinispan.counter.api.CounterConfiguration; import org.infinispan.counter.api.CounterManager; import org.infinispan.counter.api.CounterType; import org.infinispan.counter.util.StrongTestCounter; import org.testng.annotations.Test; /** * A simple consistency test. * * @author Pedro Ruivo * @since 9.0 */ @Test(groups = "functional", testName = "counter.StrongCounterTest") public class StrongCounterTest extends AbstractCounterTest<StrongTestCounter> { private static final int CLUSTER_SIZE = 4; public void testUniqueReturnValues(Method method) throws ExecutionException, InterruptedException, TimeoutException { final List<Future<List<Long>>> workers = new ArrayList<>(CLUSTER_SIZE); final String counterName = method.getName(); final CyclicBarrier barrier = new CyclicBarrier(CLUSTER_SIZE); final long counterLimit = 1000; for (int i = 0; i < CLUSTER_SIZE; ++i) { final int cmIndex = i; workers.add(fork(() -> { List<Long> retValues = new LinkedList<>(); CounterManager manager = counterManager(cmIndex); StrongTestCounter counter = createCounter(manager, counterName, 0); long lastRet = 0; barrier.await(); while (lastRet < counterLimit) { lastRet = counter.addAndGet(1); retValues.add(lastRet); } return retValues; })); } final Set<Long> uniqueValuesCheck = new HashSet<>(); for (Future<List<Long>> w : workers) { List<Long> returnValues = w.get(1, TimeUnit.MINUTES); for (Long l : returnValues) { assertTrue(format("Duplicated value %d", l), uniqueValuesCheck.add(l)); } } for (long l = 1; l < (counterLimit + 3); ++l) { assertTrue(format("Value %d does not exists!", l), uniqueValuesCheck.contains(l)); } } public void testCompareAndSet(Method method) { final String counterName = method.getName(); TestContext context = new TestContext(); context.printSeed(counterName); long expect = context.random.nextLong(); long value = context.random.nextLong(); StrongTestCounter counter = createCounter(counterManager(0), counterName, expect); for (int i = 0; i < 10; ++i) { assertTrue(counter.compareAndSet(expect, value)); assertEquals(value, counter.getValue()); expect = value; value = context.random.nextLong(); } for (int i = 0; i < 10; ++i) { long notExpected = context.random.nextLong(); while (expect == notExpected) { notExpected = context.random.nextLong(); } assertFalse(counter.compareAndSet(notExpected, value)); assertEquals(expect, counter.getValue()); } } public void testCompareAndSetMaxAndMinLong(Method method) { final String counterName = method.getName(); StrongTestCounter counter = createCounter(counterManager(0), counterName, 0); assertFalse(counter.compareAndSet(-1, Long.MAX_VALUE)); assertEquals(0, counter.getValue()); assertTrue(counter.compareAndSet(0, Long.MAX_VALUE)); assertEquals(Long.MAX_VALUE, counter.getValue()); counter.reset(); assertFalse(counter.compareAndSet(-1, Long.MIN_VALUE)); assertEquals(0, counter.getValue()); assertTrue(counter.compareAndSet(0, Long.MIN_VALUE)); assertEquals(Long.MIN_VALUE, counter.getValue()); } @Override protected StrongTestCounter createCounter(CounterManager counterManager, String counterName, long initialValue) { counterManager.defineCounter(counterName, CounterConfiguration.builder(CounterType.UNBOUNDED_STRONG).initialValue(initialValue).build()); return new StrongTestCounter(counterManager.getStrongCounter(counterName)); } @Override protected void assertMaxValueAfterMaxValue(StrongTestCounter counter, long delta) { assertEquals(Long.MAX_VALUE, counter.addAndGet(delta)); assertEquals(Long.MAX_VALUE, counter.getValue()); } @Override protected void addAndAssertResult(StrongTestCounter counter, long delta, long expected) { assertEquals(format("Wrong return value after adding %d", delta), expected, counter.addAndGet(delta)); assertEquals("Wrong return value of counter.getNewValue()", expected, counter.getValue()); } @Override protected void assertMinValueAfterMinValue(StrongTestCounter counter, long delta) { assertEquals(Long.MIN_VALUE, counter.addAndGet(delta)); assertEquals(Long.MIN_VALUE, counter.getValue()); } @Override protected int clusterSize() { return CLUSTER_SIZE; } }