View Javadoc
1   /**
2    * Logback: the reliable, generic, fast and flexible logging framework.
3    * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
4    *
5    * This program and the accompanying materials are dual-licensed under
6    * either the terms of the Eclipse Public License v1.0 as published by
7    * the Eclipse Foundation
8    *
9    *   or (per the licensee's choosing)
10   *
11   * under the terms of the GNU Lesser General Public License version 2.1
12   * as published by the Free Software Foundation.
13   */
14  package ch.qos.logback.core.sift;
15  
16  import ch.qos.logback.core.Appender;
17  import ch.qos.logback.core.Context;
18  import ch.qos.logback.core.ContextBase;
19  import ch.qos.logback.core.joran.spi.JoranException;
20  import ch.qos.logback.core.read.ListAppender;
21  import ch.qos.logback.core.testUtil.RandomUtil;
22  import org.junit.Before;
23  import org.junit.Test;
24  
25  import java.util.ArrayList;
26  import java.util.List;
27  
28  import static org.junit.Assert.*;
29  
30  /**
31   * Relatively straightforward unit tests for AppenderTracker.
32   */
33  public class AppenderTrackerTest {
34  
35      Context context = new ContextBase();
36      ListAppenderFactory listAppenderFactory = new ListAppenderFactory();
37      int diff = RandomUtil.getPositiveInt();
38      AppenderTracker<Object> appenderTracker = new AppenderTracker<Object>(context, listAppenderFactory);
39      String key = "k-" + diff;
40      long now = 3000;
41  
42      @Before
43      public void setUp() {
44      }
45  
46      @Test
47      public void removeStaleComponentsShouldNotBomb() {
48          appenderTracker.removeStaleComponents(now);
49          assertEquals(0, appenderTracker.getComponentCount());
50      }
51  
52      @Test
53      public void findingTheInexistentShouldNotBomb() {
54          assertNull(appenderTracker.find(key));
55          now += AppenderTracker.DEFAULT_TIMEOUT + 1;
56          appenderTracker.removeStaleComponents(now);
57          assertNull(appenderTracker.find(key));
58      }
59  
60      @Test
61      public void smoke() {
62          Appender<Object> a = appenderTracker.getOrCreate(key, now);
63          assertTrue(a.isStarted());
64          now += AppenderTracker.DEFAULT_TIMEOUT + 1;
65          appenderTracker.removeStaleComponents(now);
66          assertFalse(a.isStarted());
67          assertNull(appenderTracker.find(key));
68      }
69  
70      @Test
71      public void endOfLivedAppendersShouldBeRemovedAfterLingeringTimeout() {
72          Appender<Object> a = appenderTracker.getOrCreate(key, now);
73          appenderTracker.endOfLife(key);
74          now += AppenderTracker.LINGERING_TIMEOUT + 1;
75          appenderTracker.removeStaleComponents(now);
76          assertFalse(a.isStarted());
77          a = appenderTracker.find(key);
78          assertNull(a);
79      }
80  
81      @Test
82      public void endOfLivedAppenderShouldBeAvailableDuringLingeringPeriod() {
83          Appender<Object> a = appenderTracker.getOrCreate(key, now);
84          appenderTracker.endOfLife(key);
85          // clean
86          appenderTracker.removeStaleComponents(now);
87          Appender<Object> lingering = appenderTracker.getOrCreate(key, now);
88          assertTrue(lingering.isStarted());
89          assertTrue(a == lingering);
90          now += AppenderTracker.LINGERING_TIMEOUT + 1;
91          appenderTracker.removeStaleComponents(now);
92          assertFalse(a.isStarted());
93          a = appenderTracker.find(key);
94          assertNull(a);
95      }
96  
97      @Test
98      public void trackerShouldHonorMaxComponentsParameter() {
99          List<Appender<Object>> appenderList = new ArrayList<>();
100         int max = 10;
101         appenderTracker.setMaxComponents(max);
102         for (int i = 0; i < (max + 1); i++) {
103             Appender<Object> a = appenderTracker.getOrCreate(key + "-" + i, now++);
104             appenderList.add(a);
105         }
106         // cleaning only happens in removeStaleComponents
107         appenderTracker.removeStaleComponents(now++);
108         assertEquals(max, appenderTracker.allKeys().size());
109         assertNull(appenderTracker.find(key + "-" + 0));
110         assertFalse(appenderList.get(0).isStarted());
111     }
112 
113     @Test
114     public void trackerShouldHonorTimeoutParameter() {
115         List<Appender<Object>> appenderList = new ArrayList<Appender<Object>>();
116         int timeout = 2;
117         appenderTracker.setTimeout(timeout);
118         for (int i = 0; i <= timeout; i++) {
119             Appender<Object> a = appenderTracker.getOrCreate(key + "-" + i, now++);
120             appenderList.add(a);
121         }
122 
123         long numComponentsCreated = timeout + 1;
124         assertEquals(numComponentsCreated, appenderTracker.allKeys().size());
125 
126         // cleaning only happens in removeStaleComponents. The first appender should timeout
127         appenderTracker.removeStaleComponents(now++);
128 
129         // the first appender should have been removed
130         assertEquals(numComponentsCreated - 1, appenderTracker.allKeys().size());
131         assertNull(appenderTracker.find(key + "-" + 0));
132         assertFalse(appenderList.get(0).isStarted());
133 
134         // the other appenders should be in the tracker
135         for (int i = 1; i <= timeout; i++) {
136             assertNotNull(appenderTracker.find(key + "-" + i));
137             assertTrue(appenderList.get(i).isStarted());
138         }
139     }
140 
141     // ======================================================================
142     static class ListAppenderFactory implements AppenderFactory<Object> {
143 
144         public Appender<Object> buildAppender(Context context, String discriminatingValue) throws JoranException {
145             ListAppender<Object> la = new ListAppender<Object>();
146             la.setContext(context);
147             la.setName(discriminatingValue);
148             la.start();
149             return la;
150         }
151     }
152 }