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;
15  
16  import java.io.File;
17  import java.io.FileOutputStream;
18  import java.io.IOException;
19  import java.io.InputStream;
20  import java.net.URL;
21  import java.net.URLConnection;
22  import java.util.HashMap;
23  import java.util.function.Supplier;
24  import java.util.jar.JarOutputStream;
25  import java.util.zip.ZipEntry;
26  
27  import org.junit.jupiter.api.Assertions;
28  import org.junit.jupiter.api.BeforeEach;
29  import org.junit.jupiter.api.Test;
30  
31  import ch.qos.logback.core.Context;
32  import ch.qos.logback.core.ContextBase;
33  import ch.qos.logback.core.CoreConstants;
34  import ch.qos.logback.core.joran.action.Action;
35  import ch.qos.logback.core.joran.action.TopElementAction;
36  import ch.qos.logback.core.joran.action.ext.IncAction;
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.RandomUtil;
42  import ch.qos.logback.core.testUtil.TrivialStatusListener;
43  
44  public class TrivialConfiguratorTest {
45  
46      Context context = new ContextBase();
47      HashMap<ElementSelector, Supplier<Action>> rulesMap = new HashMap<>();
48  
49      @BeforeEach
50      public void setUp() {
51          // rule store is case-insensitive
52          rulesMap.put(new ElementSelector("x"), () -> new TopElementAction());
53          rulesMap.put(new ElementSelector("x/inc"), () -> new IncAction());
54  
55      }
56  
57      public void doTest(String filename) throws Exception {
58          TrivialConfigurator trivialConfigurator = new TrivialConfigurator(rulesMap);
59  
60          trivialConfigurator.setContext(context);
61          trivialConfigurator.doConfigure(filename);
62      }
63  
64      @Test
65      public void smoke() throws Exception {
66          int oldBeginCount = IncAction.beginCount;
67          int oldEndCount = IncAction.endCount;
68          int oldErrorCount = IncAction.errorCount;
69          doTest(CoreTestConstants.TEST_SRC_PREFIX + "input/joran/" + "inc.xml");
70          Assertions.assertEquals(oldErrorCount, IncAction.errorCount);
71          Assertions.assertEquals(oldBeginCount + 1, IncAction.beginCount);
72          Assertions.assertEquals(oldEndCount + 1, IncAction.endCount);
73      }
74  
75      @Test
76      public void inexistentFile() {
77          TrivialStatusListener tsl = new TrivialStatusListener();
78          tsl.start();
79          String filename = CoreTestConstants.TEST_SRC_PREFIX + "input/joran/" + "nothereBLAH.xml";
80          context.getStatusManager().add(tsl);
81          try {
82              doTest(filename);
83          } catch (Exception e) {
84              Assertions.assertTrue(e.getMessage().startsWith("Could not open ["));
85          }
86          Assertions.assertTrue(tsl.list.size() >= 1, tsl.list.size() + " should be greater than or equal to 1");
87          Status s0 = tsl.list.get(0);
88          Assertions.assertTrue(s0.getMessage().startsWith("Could not open ["));
89      }
90  
91      @Test
92      public void illFormedXML() {
93          TrivialStatusListener tsl = new TrivialStatusListener();
94          tsl.start();
95          String filename = CoreTestConstants.TEST_SRC_PREFIX + "input/joran/" + "illformed.xml";
96          context.getStatusManager().add(tsl);
97          try {
98              doTest(filename);
99          } catch (Exception e) {
100         }
101         Assertions.assertEquals(2, tsl.list.size());
102         Status s0 = tsl.list.get(0);
103         Assertions.assertTrue(s0.getMessage().startsWith(CoreConstants.XML_PARSING));
104     }
105 
106     @Test
107     public void lbcore105() throws IOException, JoranException {
108         String jarEntry = "buzz.xml";
109         File jarFile = makeRandomJarFile();
110         fillInJarFile(jarFile, jarEntry);
111         URL url = asURL(jarFile, jarEntry);
112         TrivialConfigurator tc = new TrivialConfigurator(rulesMap);
113         tc.setContext(context);
114         tc.doConfigure(url);
115         // deleting an open file fails
116         Assertions.assertTrue(jarFile.delete());
117         Assertions.assertFalse(jarFile.exists());
118     }
119 
120     @Test
121     public void lbcore127() throws IOException, JoranException {
122         String jarEntry = "buzz.xml";
123         String jarEntry2 = "lightyear.xml";
124 
125         File jarFile = makeRandomJarFile();
126         fillInJarFile(jarFile, jarEntry, jarEntry2);
127 
128         URL url1 = asURL(jarFile, jarEntry);
129         URL url2 = asURL(jarFile, jarEntry2);
130 
131         URLConnection urlConnection2 = url2.openConnection();
132         urlConnection2.setUseCaches(false);
133         InputStream is = urlConnection2.getInputStream();
134 
135         TrivialConfigurator tc = new TrivialConfigurator(rulesMap);
136         tc.setContext(context);
137         tc.doConfigure(url1);
138 
139         is.read();
140         is.close();
141 
142         // deleting an open file fails
143         Assertions.assertTrue(jarFile.delete());
144         Assertions.assertFalse(jarFile.exists());
145     }
146 
147     File makeRandomJarFile() {
148         File outputDir = new File(CoreTestConstants.OUTPUT_DIR_PREFIX);
149         outputDir.mkdirs();
150         int randomPart = RandomUtil.getPositiveInt();
151         return new File(CoreTestConstants.OUTPUT_DIR_PREFIX + "foo-" + randomPart + ".jar");
152     }
153 
154     private void fillInJarFile(File jarFile, String jarEntryName) throws IOException {
155         fillInJarFile(jarFile, jarEntryName, null);
156     }
157 
158     private void fillInJarFile(File jarFile, String jarEntryName1, String jarEntryName2) throws IOException {
159         JarOutputStream jos = new JarOutputStream(new FileOutputStream(jarFile));
160         jos.putNextEntry(new ZipEntry(jarEntryName1));
161         jos.write("<x/>".getBytes());
162         jos.closeEntry();
163         if (jarEntryName2 != null) {
164             jos.putNextEntry(new ZipEntry(jarEntryName2));
165             jos.write("<y/>".getBytes());
166             jos.closeEntry();
167         }
168         jos.close();
169     }
170 
171     URL asURL(File jarFile, String jarEntryName) throws IOException {
172         URL innerURL = jarFile.toURI().toURL();
173         return new URL("jar:" + innerURL + "!/" + jarEntryName);
174     }
175 
176 }