View Javadoc
1   package ch.qos.logback.classic;
2   
3   import java.util.concurrent.CyclicBarrier;
4   
5   import org.junit.Ignore;
6   import org.junit.Test;
7   
8   import ch.qos.logback.core.contention.AbstractMultiThreadedHarness;
9   import ch.qos.logback.core.contention.RunnableWithCounterAndDone;
10  import ch.qos.logback.core.testUtil.StatusChecker;
11  
12  @Ignore
13  public class LoggerContextConcurrentResetTest {
14      static int CONCURRENT_RESET_THREAD_COUNT = 10;
15  
16      // see http://jira.qos.ch/browse/LOGBACK-397
17      @Test(timeout = 1000)
18      public void concurrentReset() throws InterruptedException {
19          LoggerContext loggerContext = new LoggerContext();
20          CyclicBarrier cyclicBarrier = new CyclicBarrier(CONCURRENT_RESET_THREAD_COUNT);
21          StatusChecker statusChecker = new StatusChecker(loggerContext);
22          int desiredResetCount = 100;
23          RunnableWithCounterAndDone[] runnableArray = buildRunnableArray(loggerContext, cyclicBarrier);
24          Harness harness = new Harness((Resetter) runnableArray[0], desiredResetCount);
25          harness.execute(runnableArray);
26          statusChecker.assertIsErrorFree();
27      }
28  
29      class Harness extends AbstractMultiThreadedHarness {
30          int desiredResetCount;
31          Resetter resetter;
32  
33          Harness(Resetter resetter, int desiredResetCount) {
34              this.resetter = resetter;
35              this.desiredResetCount = desiredResetCount;
36          }
37  
38          public void waitUntilEndCondition() throws InterruptedException {
39              while (resetter.getCounter() < desiredResetCount) {
40                  Thread.yield();
41              }
42          }
43      }
44  
45      static class GetLoggerRunnable extends RunnableWithCounterAndDone {
46  
47          final int burstLength = 30;
48          LoggerContext loggerContext;
49          CyclicBarrier cyclicBarrier;
50          String nameSuffix;
51  
52          GetLoggerRunnable(LoggerContext loggerContext, CyclicBarrier cyclicBarrier, String nameSuffix) {
53              this.loggerContext = loggerContext;
54              this.cyclicBarrier = cyclicBarrier;
55              this.nameSuffix = nameSuffix;
56          }
57  
58          public void run() {
59              try {
60                  cyclicBarrier.await();
61              } catch (Exception e) {
62              }
63  
64              while (!isDone()) {
65                  long i = counter % burstLength;
66                  loggerContext.getLogger("org.bla." + nameSuffix + ".x" + i);
67                  counter++;
68                  if (i == 0) {
69                      Thread.yield();
70                  }
71              }
72          }
73      }
74  
75      static class Resetter extends RunnableWithCounterAndDone {
76          LoggerContext loggerContext;
77          CyclicBarrier cyclicBarrier;
78          public int resetCount = 0;
79  
80          Resetter(LoggerContext loggerContext, CyclicBarrier cyclicBarrier) {
81              this.loggerContext = loggerContext;
82              this.cyclicBarrier = cyclicBarrier;
83          }
84  
85          public void run() {
86              try {
87                  cyclicBarrier.await();
88              } catch (Exception e) {
89              }
90              while (!isDone()) {
91                  loggerContext.reset();
92                  counter++;
93                  Thread.yield();
94              }
95          }
96      }
97  
98      private RunnableWithCounterAndDone[] buildRunnableArray(LoggerContext loggerContext, CyclicBarrier cyclicBarrier) {
99          RunnableWithCounterAndDone[] rArray = new RunnableWithCounterAndDone[CONCURRENT_RESET_THREAD_COUNT];
100         rArray[0] = new Resetter(loggerContext, cyclicBarrier);
101         for (int i = 1; i < CONCURRENT_RESET_THREAD_COUNT; i++) {
102             rArray[i] = new GetLoggerRunnable(loggerContext, cyclicBarrier, "mouse-" + i);
103         }
104         return rArray;
105     }
106 }