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.jupiter.api.Assertions;
23  import org.junit.jupiter.api.BeforeEach;
24  import org.junit.jupiter.api.Test;
25  
26  import java.util.ArrayList;
27  import java.util.List;
28  
29  /**
30   * Relatively straightforward unit tests for AppenderTracker.
31   */
32  public class AppenderTrackerTest {
33  
34      Context context = new ContextBase();
35      ListAppenderFactory listAppenderFactory = new ListAppenderFactory();
36      int diff = RandomUtil.getPositiveInt();
37      AppenderTracker<Object> appenderTracker = new AppenderTracker<Object>(context, listAppenderFactory);
38      String key = "k-" + diff;
39      long now = 3000;
40  
41      @BeforeEach
42      public void setUp() {
43      }
44  
45      @Test
46      public void removeStaleComponentsShouldNotBomb() {
47          appenderTracker.removeStaleComponents(now);
48          Assertions.assertEquals(0, appenderTracker.getComponentCount());
49      }
50  
51      @Test
52      public void findingTheInexistentShouldNotBomb() {
53          Assertions.assertNull(appenderTracker.find(key));
54          now += AppenderTracker.DEFAULT_TIMEOUT + 1;
55          appenderTracker.removeStaleComponents(now);
56          Assertions.assertNull(appenderTracker.find(key));
57      }
58  
59      @Test
60      public void smoke() {
61          Appender<Object> a = appenderTracker.getOrCreate(key, now);
62          Assertions.assertTrue(a.isStarted());
63          now += AppenderTracker.DEFAULT_TIMEOUT + 1;
64          appenderTracker.removeStaleComponents(now);
65          Assertions.assertFalse(a.isStarted());
66          Assertions.assertNull(appenderTracker.find(key));
67      }
68  
69      @Test
70      public void endOfLivedAppendersShouldBeRemovedAfterLingeringTimeout() {
71          Appender<Object> a = appenderTracker.getOrCreate(key, now);
72          appenderTracker.endOfLife(key);
73          now += AppenderTracker.LINGERING_TIMEOUT + 1;
74          appenderTracker.removeStaleComponents(now);
75          Assertions.assertFalse(a.isStarted());
76          a = appenderTracker.find(key);
77          Assertions.assertNull(a);
78      }
79  
80      @Test
81      public void endOfLivedAppenderShouldBeAvailableDuringLingeringPeriod() {
82          Appender<Object> a = appenderTracker.getOrCreate(key, now);
83          appenderTracker.endOfLife(key);
84          // clean
85          appenderTracker.removeStaleComponents(now);
86          Appender<Object> lingering = appenderTracker.getOrCreate(key, now);
87          Assertions.assertTrue(lingering.isStarted());
88          Assertions.assertTrue(a == lingering);
89          now += AppenderTracker.LINGERING_TIMEOUT + 1;
90          appenderTracker.removeStaleComponents(now);
91          Assertions.assertFalse(a.isStarted());
92          a = appenderTracker.find(key);
93          Assertions.assertNull(a);
94      }
95  
96      @Test
97      public void trackerShouldHonorMaxComponentsParameter() {
98          List<Appender<Object>> appenderList = new ArrayList<>();
99          int max = 10;
100         appenderTracker.setMaxComponents(max);
101         for (int i = 0; i < (max + 1); i++) {
102             Appender<Object> a = appenderTracker.getOrCreate(key + "-" + i, now++);
103             appenderList.add(a);
104         }
105         // cleaning only happens in removeStaleComponents
106         appenderTracker.removeStaleComponents(now++);
107         Assertions.assertEquals(max, appenderTracker.allKeys().size());
108         Assertions.assertNull(appenderTracker.find(key + "-" + 0));
109         Assertions.assertFalse(appenderList.get(0).isStarted());
110     }
111 
112     @Test
113     public void trackerShouldHonorTimeoutParameter() {
114         List<Appender<Object>> appenderList = new ArrayList<Appender<Object>>();
115         int timeout = 2;
116         appenderTracker.setTimeout(timeout);
117         for (int i = 0; i <= timeout; i++) {
118             Appender<Object> a = appenderTracker.getOrCreate(key + "-" + i, now++);
119             appenderList.add(a);
120         }
121 
122         long numComponentsCreated = timeout + 1;
123         Assertions.assertEquals(numComponentsCreated, appenderTracker.allKeys().size());
124 
125         // cleaning only happens in removeStaleComponents. The first appender should
126         // time out
127         appenderTracker.removeStaleComponents(now++);
128 
129         // the first appender should have been removed
130         Assertions.assertEquals(numComponentsCreated - 1, appenderTracker.allKeys().size());
131         Assertions.assertNull(appenderTracker.find(key + "-" + 0));
132         Assertions.assertFalse(appenderList.get(0).isStarted());
133 
134         // the other appenders should be in the tracker
135         for (int i = 1; i <= timeout; i++) {
136             Assertions.assertNotNull(appenderTracker.find(key + "-" + i));
137             Assertions.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 }