001package ch.qos.logback.classic; 002 003import java.util.concurrent.CyclicBarrier; 004 005import org.junit.Ignore; 006import org.junit.Test; 007 008import ch.qos.logback.core.contention.AbstractMultiThreadedHarness; 009import ch.qos.logback.core.contention.RunnableWithCounterAndDone; 010import ch.qos.logback.core.testUtil.StatusChecker; 011 012@Ignore 013public class LoggerContextConcurrentResetTest { 014 static int CONCURRENT_RESET_THREAD_COUNT = 10; 015 016 // see http://jira.qos.ch/browse/LOGBACK-397 017 @Test(timeout = 1000) 018 public void concurrentReset() throws InterruptedException { 019 LoggerContext loggerContext = new LoggerContext(); 020 CyclicBarrier cyclicBarrier = new CyclicBarrier(CONCURRENT_RESET_THREAD_COUNT); 021 StatusChecker statusChecker = new StatusChecker(loggerContext); 022 int desiredResetCount = 100; 023 RunnableWithCounterAndDone[] runnableArray = buildRunnableArray(loggerContext, cyclicBarrier); 024 Harness harness = new Harness((Resetter) runnableArray[0], desiredResetCount); 025 harness.execute(runnableArray); 026 statusChecker.assertIsErrorFree(); 027 } 028 029 class Harness extends AbstractMultiThreadedHarness { 030 int desiredResetCount; 031 Resetter resetter; 032 033 Harness(Resetter resetter, int desiredResetCount) { 034 this.resetter = resetter; 035 this.desiredResetCount = desiredResetCount; 036 } 037 038 public void waitUntilEndCondition() throws InterruptedException { 039 while (resetter.getCounter() < desiredResetCount) { 040 Thread.yield(); 041 } 042 } 043 } 044 045 static class GetLoggerRunnable extends RunnableWithCounterAndDone { 046 047 final int burstLength = 30; 048 LoggerContext loggerContext; 049 CyclicBarrier cyclicBarrier; 050 String nameSuffix; 051 052 GetLoggerRunnable(LoggerContext loggerContext, CyclicBarrier cyclicBarrier, String nameSuffix) { 053 this.loggerContext = loggerContext; 054 this.cyclicBarrier = cyclicBarrier; 055 this.nameSuffix = nameSuffix; 056 } 057 058 public void run() { 059 try { 060 cyclicBarrier.await(); 061 } catch (Exception e) { 062 } 063 064 while (!isDone()) { 065 long i = counter % burstLength; 066 loggerContext.getLogger("org.bla." + nameSuffix + ".x" + i); 067 counter++; 068 if (i == 0) { 069 Thread.yield(); 070 } 071 } 072 } 073 } 074 075 static class Resetter extends RunnableWithCounterAndDone { 076 LoggerContext loggerContext; 077 CyclicBarrier cyclicBarrier; 078 public int resetCount = 0; 079 080 Resetter(LoggerContext loggerContext, CyclicBarrier cyclicBarrier) { 081 this.loggerContext = loggerContext; 082 this.cyclicBarrier = cyclicBarrier; 083 } 084 085 public void run() { 086 try { 087 cyclicBarrier.await(); 088 } catch (Exception e) { 089 } 090 while (!isDone()) { 091 loggerContext.reset(); 092 counter++; 093 Thread.yield(); 094 } 095 } 096 } 097 098 private RunnableWithCounterAndDone[] buildRunnableArray(LoggerContext loggerContext, CyclicBarrier cyclicBarrier) { 099 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}