001/**
002 * Logback: the reliable, generic, fast and flexible logging framework.
003 * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
004 *
005 * This program and the accompanying materials are dual-licensed under
006 * either the terms of the Eclipse Public License v1.0 as published by
007 * the Eclipse Foundation
008 *
009 *   or (per the licensee's choosing)
010 *
011 * under the terms of the GNU Lesser General Public License version 2.1
012 * as published by the Free Software Foundation.
013 */
014package ch.qos.logback.core.joran;
015
016import static org.junit.Assert.assertEquals;
017import static org.junit.Assert.assertFalse;
018import static org.junit.Assert.assertTrue;
019
020import java.io.File;
021import java.io.FileOutputStream;
022import java.io.IOException;
023import java.io.InputStream;
024import java.net.URL;
025import java.net.URLConnection;
026import java.util.HashMap;
027import java.util.jar.JarOutputStream;
028import java.util.zip.ZipEntry;
029
030import org.junit.Test;
031
032import ch.qos.logback.core.Context;
033import ch.qos.logback.core.ContextBase;
034import ch.qos.logback.core.CoreConstants;
035import ch.qos.logback.core.joran.action.Action;
036import ch.qos.logback.core.joran.action.ext.IncAction;
037import ch.qos.logback.core.joran.spi.ElementSelector;
038import ch.qos.logback.core.joran.spi.JoranException;
039import ch.qos.logback.core.status.Status;
040import ch.qos.logback.core.testUtil.CoreTestConstants;
041import ch.qos.logback.core.testUtil.RandomUtil;
042import ch.qos.logback.core.testUtil.TrivialStatusListener;
043
044public class TrivialConfiguratorTest {
045
046    Context context = new ContextBase();
047    HashMap<ElementSelector, Action> rulesMap = new HashMap<ElementSelector, Action>();
048
049    public void doTest(String filename) throws Exception {
050
051        // rule store is case insensitve
052        rulesMap.put(new ElementSelector("x/inc"), new IncAction());
053
054        TrivialConfigurator trivialConfigurator = new TrivialConfigurator(rulesMap);
055
056        trivialConfigurator.setContext(context);
057        trivialConfigurator.doConfigure(filename);
058    }
059
060    @Test
061    public void smoke() throws Exception {
062        int oldBeginCount = IncAction.beginCount;
063        int oldEndCount = IncAction.endCount;
064        int oldErrorCount = IncAction.errorCount;
065        doTest(CoreTestConstants.TEST_SRC_PREFIX + "input/joran/" + "inc.xml");
066        assertEquals(oldErrorCount, IncAction.errorCount);
067        assertEquals(oldBeginCount + 1, IncAction.beginCount);
068        assertEquals(oldEndCount + 1, IncAction.endCount);
069    }
070
071    @Test
072    public void inexistentFile() {
073        TrivialStatusListener tsl = new TrivialStatusListener();
074        tsl.start();
075        String filename = CoreTestConstants.TEST_SRC_PREFIX + "input/joran/" + "nothereBLAH.xml";
076        context.getStatusManager().add(tsl);
077        try {
078            doTest(filename);
079        } catch (Exception e) {
080            assertTrue(e.getMessage().startsWith("Could not open ["));
081        }
082        assertTrue(tsl.list.size() + " should be greater than or equal to 1", tsl.list.size() >= 1);
083        Status s0 = tsl.list.get(0);
084        assertTrue(s0.getMessage().startsWith("Could not open ["));
085    }
086
087    @Test
088    public void illFormedXML() {
089        TrivialStatusListener tsl = new TrivialStatusListener();
090        tsl.start();
091        String filename = CoreTestConstants.TEST_SRC_PREFIX + "input/joran/" + "illformed.xml";
092        context.getStatusManager().add(tsl);
093        try {
094            doTest(filename);
095        } catch (Exception e) {
096        }
097        assertEquals(2, tsl.list.size());
098        Status s0 = tsl.list.get(0);
099        assertTrue(s0.getMessage().startsWith(CoreConstants.XML_PARSING));
100    }
101
102    @Test
103    public void lbcore105() throws IOException, JoranException {
104        String jarEntry = "buzz.xml";
105        File jarFile = makeRandomJarFile();
106        fillInJarFile(jarFile, jarEntry);
107        URL url = asURL(jarFile, jarEntry);
108        TrivialConfigurator tc = new TrivialConfigurator(rulesMap);
109        tc.setContext(context);
110        tc.doConfigure(url);
111        // deleting an open file fails
112        assertTrue(jarFile.delete());
113        assertFalse(jarFile.exists());
114    }
115
116    @Test
117    public void lbcore127() throws IOException, JoranException {
118        String jarEntry = "buzz.xml";
119        String jarEntry2 = "lightyear.xml";
120
121        File jarFile = makeRandomJarFile();
122        fillInJarFile(jarFile, jarEntry, jarEntry2);
123
124        URL url1 = asURL(jarFile, jarEntry);
125        URL url2 = asURL(jarFile, jarEntry2);
126
127        URLConnection urlConnection2 = url2.openConnection();
128        urlConnection2.setUseCaches(false);
129        InputStream is = urlConnection2.getInputStream();
130
131        TrivialConfigurator tc = new TrivialConfigurator(rulesMap);
132        tc.setContext(context);
133        tc.doConfigure(url1);
134
135        is.read();
136        is.close();
137
138        // deleting an open file fails
139        assertTrue(jarFile.delete());
140        assertFalse(jarFile.exists());
141    }
142
143    File makeRandomJarFile() {
144        File outputDir = new File(CoreTestConstants.OUTPUT_DIR_PREFIX);
145        outputDir.mkdirs();
146        int randomPart = RandomUtil.getPositiveInt();
147        return new File(CoreTestConstants.OUTPUT_DIR_PREFIX + "foo-" + randomPart + ".jar");
148    }
149
150    private void fillInJarFile(File jarFile, String jarEntryName) throws IOException {
151        fillInJarFile(jarFile, jarEntryName, null);
152    }
153
154    private void fillInJarFile(File jarFile, String jarEntryName1, String jarEntryName2) throws IOException {
155        JarOutputStream jos = new JarOutputStream(new FileOutputStream(jarFile));
156        jos.putNextEntry(new ZipEntry(jarEntryName1));
157        jos.write("<x/>".getBytes());
158        jos.closeEntry();
159        if (jarEntryName2 != null) {
160            jos.putNextEntry(new ZipEntry(jarEntryName2));
161            jos.write("<y/>".getBytes());
162            jos.closeEntry();
163        }
164        jos.close();
165    }
166
167    URL asURL(File jarFile, String jarEntryName) throws IOException {
168        URL innerURL = jarFile.toURI().toURL();
169        return new URL("jar:" + innerURL + "!/" + jarEntryName);
170    }
171
172}