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