View Javadoc
1   package org.slf4j.impl;
2   
3   import static org.junit.Assert.assertEquals;
4   import static org.junit.Assert.assertNotNull;
5   
6   import java.util.List;
7   import java.util.Random;
8   import java.util.concurrent.BrokenBarrierException;
9   import java.util.concurrent.CyclicBarrier;
10  import java.util.concurrent.atomic.AtomicLong;
11  
12  import org.junit.After;
13  import org.junit.Before;
14  import org.junit.Test;
15  import org.slf4j.Logger;
16  import org.slf4j.LoggerFactory;
17  import org.slf4j.LoggerFactoryFriend;
18  import org.slf4j.helpers.SubstituteLogger;
19  
20  import ch.qos.logback.classic.ClassicConstants;
21  import ch.qos.logback.classic.ClassicTestConstants;
22  import ch.qos.logback.classic.spi.ILoggingEvent;
23  import ch.qos.logback.core.read.ListAppender;
24  
25  public class MultithreadedInitializationTest {
26  
27      final static int THREAD_COUNT = 4 + Runtime.getRuntime().availableProcessors() * 2;
28      private static AtomicLong EVENT_COUNT = new AtomicLong(0);
29      final CyclicBarrier barrier = new CyclicBarrier(THREAD_COUNT + 1);
30  
31      int diff = new Random().nextInt(10000);
32      String loggerName = "org.slf4j.impl.MultithreadedInitializationTest";
33  
34      @Before
35      public void setUp() throws Exception {
36          System.setProperty(ClassicConstants.CONFIG_FILE_PROPERTY, ClassicTestConstants.INPUT_PREFIX + "listAppender.xml");
37          LoggerFactoryFriend.reset();
38      }
39  
40      @After
41      public void tearDown() throws Exception {
42          System.clearProperty(ClassicConstants.CONFIG_FILE_PROPERTY);
43      }
44  
45      @Test
46      public void multiThreadedInitialization() throws InterruptedException, BrokenBarrierException {
47          LoggerAccessingThread[] accessors = harness();
48  
49          for (LoggerAccessingThread accessor : accessors) {
50              EVENT_COUNT.getAndIncrement();
51              accessor.logger.info("post harness");
52          }
53  
54          Logger logger = LoggerFactory.getLogger(loggerName + ".slowInitialization-" + diff);
55          logger.info("hello");
56          EVENT_COUNT.getAndIncrement();
57  
58          List<ILoggingEvent> events = getRecordedEvents();
59          assertEquals(EVENT_COUNT.get(), events.size());
60      }
61  
62      private List<ILoggingEvent> getRecordedEvents() {
63          ch.qos.logback.classic.Logger root = (ch.qos.logback.classic.Logger) LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME);
64  
65          ListAppender<ILoggingEvent> la = (ListAppender<ILoggingEvent>) root.getAppender("LIST");
66          assertNotNull(la);
67          return la.list;
68      }
69  
70      private static LoggerAccessingThread[] harness() throws InterruptedException, BrokenBarrierException {
71          LoggerAccessingThread[] threads = new LoggerAccessingThread[THREAD_COUNT];
72          final CyclicBarrier barrier = new CyclicBarrier(THREAD_COUNT + 1);
73          for (int i = 0; i < THREAD_COUNT; i++) {
74              threads[i] = new LoggerAccessingThread(barrier, i);
75              threads[i].start();
76          }
77  
78          barrier.await();
79          for (int i = 0; i < THREAD_COUNT; i++) {
80              threads[i].join();
81          }
82          return threads;
83      }
84  
85      static class LoggerAccessingThread extends Thread {
86          final CyclicBarrier barrier;
87          Logger logger;
88          int count;
89  
90          LoggerAccessingThread(CyclicBarrier barrier, int count) {
91              this.barrier = barrier;
92              this.count = count;
93          }
94  
95          public void run() {
96              try {
97                  barrier.await();
98              } catch (Exception e) {
99                  e.printStackTrace();
100             }
101             logger = LoggerFactory.getLogger(this.getClass().getName() + "-" + count);
102             logger.info("in run method");
103             if (logger instanceof SubstituteLogger) {
104                 SubstituteLogger substLogger = (SubstituteLogger) logger;
105                 if (!substLogger.createdPostInitialization) {
106                     EVENT_COUNT.getAndIncrement();
107                 }
108             } else {
109                 EVENT_COUNT.getAndIncrement();
110             }
111         }
112     };
113 
114 }