View Javadoc

    1   package org.slf4j.helpers;
    2
    3   import static org.junit.Assert.assertTrue;
    4   import static org.junit.Assert.fail;
    5
    6   import java.util.ArrayList;
    7   import java.util.Collections;
    8   import java.util.List;
    9   import java.util.Random;
    10  import java.util.concurrent.BrokenBarrierException;
    11  import java.util.concurrent.CyclicBarrier;
    12  import java.util.concurrent.atomic.AtomicLong;
    13
    14  import org.junit.Test;
    15  import org.slf4j.Logger;
    16  import org.slf4j.LoggerAccessingThread;
    17  import org.slf4j.LoggerFactory;
    18  import org.slf4j.event.EventRecodingLogger;
    19
    20  abstract public class MultithreadedInitializationTest {
    21      final protected static int THREAD_COUNT = 4 + Runtime.getRuntime().availableProcessors() * 2;
    22
    23      private final List<Logger> createdLoggers = Collections.synchronizedList(new ArrayList<Logger>());
    24
    25      final private AtomicLong eventCount = new AtomicLong(0);
    26      final private CyclicBarrier barrier = new CyclicBarrier(THREAD_COUNT + 1);
    27
    28      int diff = new Random().nextInt(10000);
    29
    30      @Test
    31      public void multiThreadedInitialization() throws InterruptedException, BrokenBarrierException {
    32          @SuppressWarnings("unused")
    33          LoggerAccessingThread[] accessors = harness();
    34
    35          Logger logger = LoggerFactory.getLogger(getClass().getName());
    36          logger.info("hello");
    37          eventCount.getAndIncrement();
    38
    39          assertAllSubstLoggersAreFixed();
    40          long recordedEventCount = getRecordedEventCount();
    41          int LENIENCY_COUNT = 16;
    42
    43          long expectedEventCount = eventCount.get() + extraLogEvents();
    44
    45          assertTrue(expectedEventCount + " >= " + recordedEventCount, expectedEventCount >= recordedEventCount);
    46          assertTrue(expectedEventCount + " < " + recordedEventCount + "+" + LENIENCY_COUNT, expectedEventCount < recordedEventCount + LENIENCY_COUNT);
    47      }
    48
    49      abstract protected long getRecordedEventCount();
    50
    51      protected int extraLogEvents() {
    52          return 0;
    53      }
    54
    55      private void assertAllSubstLoggersAreFixed() {
    56          for (Logger logger : createdLoggers) {
    57              if (logger instanceof SubstituteLogger) {
    58                  SubstituteLogger substLogger = (SubstituteLogger) logger;
    59                  if (substLogger.delegate() instanceof EventRecodingLogger)
    60                      fail("substLogger " + substLogger.getName() + " has a delegate of type EventRecodingLogger");
    61              }
    62          }
    63      }
    64
    65      private LoggerAccessingThread[] harness() throws InterruptedException, BrokenBarrierException {
    66          LoggerAccessingThread[] threads = new LoggerAccessingThread[THREAD_COUNT];
    67          for (int i = 0; i < THREAD_COUNT; i++) {
    68              threads[i] = new LoggerAccessingThread(barrier, createdLoggers, i, eventCount);
    69              threads[i].start();
    70          }
    71
    72          // trigger barrier
    73          barrier.await();
    74
    75          for (int i = 0; i < THREAD_COUNT; i++) {
    76              threads[i].join();
    77          }
    78
    79          return threads;
    80      }
    81  }