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  }