blob: c534bad1aa7884e04f4365abf01d6bdb91baeceb [file] [log] [blame]
package org.slf4j.testHarness;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.atomic.AtomicLong;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerAccessingThread;
import org.slf4j.LoggerFactory;
import org.slf4j.event.EventRecordingLogger;
import org.slf4j.helpers.SubstituteLogger;
abstract public class MultithreadedInitializationTest {
final protected static int THREAD_COUNT = 4 + Runtime.getRuntime().availableProcessors() * 2;
private final List<Logger> createdLoggers = Collections.synchronizedList(new ArrayList<>());
final protected AtomicLong eventCount = new AtomicLong(0);
final private CyclicBarrier barrier = new CyclicBarrier(THREAD_COUNT + 1);
@Test
public void multiThreadedInitialization() throws InterruptedException, BrokenBarrierException {
@SuppressWarnings("unused")
LoggerAccessingThread[] accessors = harness();
Logger logger = LoggerFactory.getLogger(getClass().getName());
logger.info("hello");
eventCount.getAndIncrement();
assertAllSubstLoggersAreFixed();
long recordedEventCount = getRecordedEventCount();
int LENIENCY_COUNT = 30;
long expectedEventCount = eventCount.get() + extraLogEvents();
assertTrue(expectedEventCount + " >= " + recordedEventCount, expectedEventCount >= recordedEventCount);
assertTrue(expectedEventCount + " < " + recordedEventCount + "+" + LENIENCY_COUNT, expectedEventCount < recordedEventCount + LENIENCY_COUNT);
}
abstract protected long getRecordedEventCount();
protected int extraLogEvents() {
return 0;
}
private void assertAllSubstLoggersAreFixed() {
for (Logger logger : createdLoggers) {
if (logger instanceof SubstituteLogger) {
SubstituteLogger substLogger = (SubstituteLogger) logger;
if (substLogger.delegate() instanceof EventRecordingLogger)
fail("substLogger " + substLogger.getName() + " has a delegate of type EventRecodingLogger");
}
}
}
private LoggerAccessingThread[] harness() throws InterruptedException, BrokenBarrierException {
LoggerAccessingThread[] threads = new LoggerAccessingThread[THREAD_COUNT];
for (int i = 0; i < THREAD_COUNT; i++) {
threads[i] = new LoggerAccessingThread(barrier, createdLoggers, i, eventCount);
threads[i].start();
}
// trigger barrier
barrier.await();
for (int i = 0; i < THREAD_COUNT; i++) {
threads[i].join();
}
return threads;
}
}