package org.jctools.counters; import static org.junit.Assert.*; import java.util.ArrayList; import java.util.Collection; import java.util.concurrent.CountDownLatch; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicLong; import org.jctools.util.JvmInfo; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; /** * @author Tolstopyatov Vsevolod */ @RunWith(Parameterized.class) public class FixedSizeStripedLongCounterTest { @Parameterized.Parameters public static Collection<Object[]> parameters() { int stripesCount = JvmInfo.CPUs * 2; ArrayList<Object[]> list = new ArrayList<>(); list.add(new Counter[]{new FixedSizeStripedLongCounterV6(stripesCount)}); list.add(new Counter[]{new FixedSizeStripedLongCounterV8(stripesCount)}); return list; } private final Counter counter; public FixedSizeStripedLongCounterTest(Counter counter) { this.counter = counter; } @Test public void testCounterSanity() { long expected = 1000L; for (int i = 0; i < expected; i++) { counter.inc(); } assertSanity(expected); } @Test public void testMultipleThreadsCounterSanity() throws Exception { int threadsCount = JvmInfo.CPUs; AtomicLong summary = new AtomicLong(); AtomicBoolean running = new AtomicBoolean(true); CountDownLatch startLatch = new CountDownLatch(1); CountDownLatch finishLatch = new CountDownLatch(threadsCount); AtomicBoolean fail = new AtomicBoolean(false); for (int i = 0; i < threadsCount; i++) { new Thread(() -> { try { Counter c = counter; startLatch.await(); long local = 0; while (running.get()) { c.inc(); local++; } summary.addAndGet(local); } catch (Exception e) { fail.set(true); } finally { finishLatch.countDown(); } }).start(); } startLatch.countDown(); Thread.sleep(1000); running.set(false); finishLatch.await(); assertFalse(fail.get()); assertSanity(summary.get()); } private void assertSanity(long expected) { assertEquals(expected, counter.get()); assertEquals(expected, counter.getAndReset()); assertEquals(0L, counter.get()); } }