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.joran.action;
15  
16  import static org.junit.Assert.assertEquals;
17  import static org.junit.Assert.assertTrue;
18  
19  import java.io.File;
20  import java.io.FileInputStream;
21  import java.io.FileOutputStream;
22  import java.io.IOException;
23  import java.net.MalformedURLException;
24  import java.util.Arrays;
25  import java.util.HashMap;
26  import java.util.Stack;
27  
28  import org.junit.After;
29  import org.junit.Before;
30  import org.junit.Test;
31  import org.xml.sax.SAXParseException;
32  
33  import ch.qos.logback.core.Context;
34  import ch.qos.logback.core.ContextBase;
35  import ch.qos.logback.core.joran.TrivialConfigurator;
36  import ch.qos.logback.core.joran.action.ext.StackAction;
37  import ch.qos.logback.core.joran.spi.ElementSelector;
38  import ch.qos.logback.core.joran.spi.JoranException;
39  import ch.qos.logback.core.status.Status;
40  import ch.qos.logback.core.testUtil.CoreTestConstants;
41  import ch.qos.logback.core.testUtil.FileTestUtil;
42  import ch.qos.logback.core.testUtil.RandomUtil;
43  import ch.qos.logback.core.testUtil.StatusChecker;
44  import ch.qos.logback.core.util.StatusPrinter;
45  
46  public class IncludeActionTest {
47  
48      final static String INCLUDE_KEY = "includeKey";
49      final static String SUB_FILE_KEY = "subFileKey";
50      final static String SECOND_FILE_KEY = "secondFileKey";
51  
52      Context context = new ContextBase();
53      StatusChecker statusChecker = new StatusChecker(context);
54      TrivialConfigurator tc;
55  
56      static final String INCLUSION_DIR_PREFIX = CoreTestConstants.JORAN_INPUT_PREFIX + "inclusion/";
57  
58      static final String TOP_BY_FILE = INCLUSION_DIR_PREFIX + "topByFile.xml";
59  
60      static final String TOP_OPTIONAL = INCLUSION_DIR_PREFIX + "topOptional.xml";
61  
62      static final String TOP_OPTIONAL_RESOURCE = INCLUSION_DIR_PREFIX + "topOptionalResource.xml";
63  
64      static final String INTERMEDIARY_FILE = INCLUSION_DIR_PREFIX + "intermediaryByFile.xml";
65  
66      static final String SUB_FILE = INCLUSION_DIR_PREFIX + "subByFile.xml";
67  
68      static final String MULTI_INCLUDE_BY_FILE = INCLUSION_DIR_PREFIX + "multiIncludeByFile.xml";
69  
70      static final String SECOND_FILE = INCLUSION_DIR_PREFIX + "second.xml";
71  
72      static final String TOP_BY_URL = INCLUSION_DIR_PREFIX + "topByUrl.xml";
73  
74      static final String TOP_BY_ENTITY = INCLUSION_DIR_PREFIX + "topByEntity.xml";
75  
76      static final String INCLUDE_BY_RESOURCE = INCLUSION_DIR_PREFIX + "topByResource.xml";
77  
78      static final String INCLUDED_FILE = INCLUSION_DIR_PREFIX + "included.xml";
79      static final String URL_TO_INCLUDE = "file:./" + INCLUDED_FILE;
80  
81      static final String INVALID = INCLUSION_DIR_PREFIX + "invalid.xml";
82  
83      static final String INCLUDED_AS_RESOURCE = "asResource/joran/inclusion/includedAsResource.xml";
84  
85      int diff = RandomUtil.getPositiveInt();
86  
87      StackAction stackAction = new StackAction();
88  
89      @Before
90      public void setUp() throws Exception {
91          FileTestUtil.makeTestOutputDir();
92          HashMap<ElementSelector, Action> rulesMap = new HashMap<ElementSelector, Action>();
93          rulesMap.put(new ElementSelector("x"), new NOPAction());
94          rulesMap.put(new ElementSelector("x/include"), new IncludeAction());
95          rulesMap.put(new ElementSelector("x/stack"), stackAction);
96  
97          tc = new TrivialConfigurator(rulesMap);
98          tc.setContext(context);
99      }
100 
101     @After
102     public void tearDown() throws Exception {
103         StatusPrinter.printInCaseOfErrorsOrWarnings(context);
104         context = null;
105         System.clearProperty(INCLUDE_KEY);
106         System.clearProperty(SECOND_FILE_KEY);
107         System.clearProperty(SUB_FILE_KEY);
108         // StackAction.reset();
109     }
110 
111     @Test
112     public void basicFile() throws JoranException {
113         System.setProperty(INCLUDE_KEY, INCLUDED_FILE);
114         tc.doConfigure(TOP_BY_FILE);
115         verifyConfig(new String[] { "IA", "IB" });
116     }
117 
118     @Test
119     public void optionalFile() throws JoranException {
120         tc.doConfigure(TOP_OPTIONAL);
121         verifyConfig(new String[] { "IA", "IB" });
122         StatusPrinter.print(context);
123     }
124 
125     @Test
126     public void optionalResource() throws JoranException {
127         tc.doConfigure(TOP_OPTIONAL_RESOURCE);
128         verifyConfig(new String[] { "IA", "IB" });
129         StatusPrinter.print(context);
130         assertEquals(Status.INFO, statusChecker.getHighestLevel(0));
131     }
132 
133     @Test
134     public void basicResource() throws JoranException {
135         System.setProperty(INCLUDE_KEY, INCLUDED_AS_RESOURCE);
136         tc.doConfigure(INCLUDE_BY_RESOURCE);
137         verifyConfig(new String[] { "AR_A", "AR_B" });
138     }
139 
140     @Test
141     public void basicURL() throws JoranException {
142         System.setProperty(INCLUDE_KEY, URL_TO_INCLUDE);
143         tc.doConfigure(TOP_BY_URL);
144         verifyConfig(new String[] { "IA", "IB" });
145     }
146 
147     @Test
148     public void noFileFound() throws JoranException {
149         System.setProperty(INCLUDE_KEY, "toto");
150         tc.doConfigure(TOP_BY_FILE);
151         assertEquals(Status.WARN, statusChecker.getHighestLevel(0));
152     }
153 
154     @Test
155     public void withCorruptFile() throws JoranException, IOException {
156         String tmpOut = copyToTemp(INVALID);
157         System.setProperty(INCLUDE_KEY, tmpOut);
158         tc.doConfigure(TOP_BY_FILE);
159         assertEquals(Status.ERROR, statusChecker.getHighestLevel(0));
160         StatusPrinter.print(context);
161         assertTrue(statusChecker.containsException(SAXParseException.class));
162 
163         // we like to erase the temp file in order to see
164         // if http://jira.qos.ch/browse/LBCORE-122 was fixed
165         File f = new File(tmpOut);
166         assertTrue(f.exists());
167         assertTrue(f.delete());
168 
169     }
170 
171     String copyToTemp(String in) throws IOException {
172         FileInputStream fis = new FileInputStream(in);
173         String out = CoreTestConstants.OUTPUT_DIR_PREFIX + "out" + diff;
174         FileOutputStream fos = new FileOutputStream(out);
175         int b;
176         while ((b = fis.read()) != -1) {
177             fos.write(b);
178         }
179         fis.close();
180         fos.close();
181         return out;
182     }
183 
184     @Test
185     public void malformedURL() throws JoranException {
186         System.setProperty(INCLUDE_KEY, "htp://logback.qos.ch");
187         tc.doConfigure(TOP_BY_URL);
188         assertEquals(Status.ERROR, statusChecker.getHighestLevel(0));
189         assertTrue(statusChecker.containsException(MalformedURLException.class));
190     }
191 
192     @Test
193     public void unknownURL() throws JoranException {
194         System.setProperty(INCLUDE_KEY, "http://logback2345.qos.ch");
195         tc.doConfigure(TOP_BY_URL);
196         assertEquals(Status.WARN, statusChecker.getHighestLevel(0));
197     }
198 
199     @Test
200     public void nestedInclude() throws JoranException {
201         System.setProperty(SUB_FILE_KEY, SUB_FILE);
202         System.setProperty(INCLUDE_KEY, INTERMEDIARY_FILE);
203         tc.doConfigure(TOP_BY_FILE);
204         Stack<String> witness = new Stack<String>();
205         witness.push("a");
206         witness.push("b");
207         witness.push("c");
208         assertEquals(witness, stackAction.getStack());
209     }
210 
211     @Test
212     public void multiInclude() throws JoranException {
213         System.setProperty(INCLUDE_KEY, INCLUDED_FILE);
214         System.setProperty(SECOND_FILE_KEY, SECOND_FILE);
215         tc.doConfigure(MULTI_INCLUDE_BY_FILE);
216         verifyConfig(new String[] { "IA", "IB", "SECOND" });
217     }
218     
219     @Test
220     public void includeAsEntity() throws JoranException {
221         tc.doConfigure(TOP_BY_ENTITY);
222         verifyConfig(new String[] { "EA", "EB" });  
223     }
224     
225     void verifyConfig(String[] expected) {
226         Stack<String> witness = new Stack<String>();
227         witness.addAll(Arrays.asList(expected));
228         assertEquals(witness, stackAction.getStack());
229     }
230 
231 
232     
233 }