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