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.classic.db;
015
016import static org.junit.Assert.assertEquals;
017import static org.junit.Assert.assertTrue;
018import static org.junit.Assert.fail;
019
020import java.sql.ResultSet;
021import java.sql.SQLException;
022import java.sql.Statement;
023import java.util.Date;
024import java.util.Map;
025
026import org.apache.log4j.MDC;
027import org.junit.After;
028import org.junit.Before;
029import org.junit.Test;
030
031import ch.qos.logback.classic.Level;
032import ch.qos.logback.classic.Logger;
033import ch.qos.logback.classic.LoggerContext;
034import ch.qos.logback.classic.spi.ILoggingEvent;
035import ch.qos.logback.classic.spi.LoggingEvent;
036import ch.qos.logback.core.db.DriverManagerConnectionSource;
037import ch.qos.logback.core.testUtil.RandomUtil;
038import ch.qos.logback.core.testUtil.StatusChecker;
039import ch.qos.logback.core.util.StatusPrinter;
040
041public class DBAppenderH2Test {
042
043    LoggerContext loggerContext = new LoggerContext();;
044    Logger logger;
045    DBAppender appender;
046    DriverManagerConnectionSource connectionSource;
047    DBAppenderH2TestFixture dbAppenderH2TestFixture;
048    int diff = RandomUtil.getPositiveInt();
049    StatusChecker checker = new StatusChecker(loggerContext);
050
051    @Before
052    public void setUp() throws SQLException {
053        dbAppenderH2TestFixture = new DBAppenderH2TestFixture();
054        dbAppenderH2TestFixture.setUp();
055        loggerContext.setName("default");
056        logger = loggerContext.getLogger("root");
057        appender = new DBAppender();
058        appender.setName("DB");
059        appender.setContext(loggerContext);
060        connectionSource = new DriverManagerConnectionSource();
061        connectionSource.setContext(loggerContext);
062        connectionSource.setDriverClass(DBAppenderH2TestFixture.H2_DRIVER_CLASS);
063        connectionSource.setUrl(dbAppenderH2TestFixture.url);
064        System.out.println("cs.url=" + dbAppenderH2TestFixture.url);
065        connectionSource.setUser(dbAppenderH2TestFixture.user);
066        connectionSource.setPassword(dbAppenderH2TestFixture.password);
067
068        connectionSource.start();
069        appender.setConnectionSource(connectionSource);
070        appender.start();
071    }
072
073    @After
074    public void tearDown() throws SQLException {
075        logger = null;
076        loggerContext = null;
077        appender = null;
078        connectionSource = null;
079        dbAppenderH2TestFixture.tearDown();
080    }
081
082    @Test
083    public void testAppendLoggingEvent() throws SQLException {
084        ILoggingEvent event = createLoggingEvent();
085
086        appender.append(event);
087
088        StatusPrinter.print(loggerContext);
089
090        Statement stmt = connectionSource.getConnection().createStatement();
091        ResultSet rs = null;
092        rs = stmt.executeQuery("SELECT * FROM logging_event");
093        if (rs.next()) {
094            assertEquals(event.getTimeStamp(), rs.getLong(DBAppender.TIMESTMP_INDEX));
095            assertEquals(event.getFormattedMessage(), rs.getString(DBAppender.FORMATTED_MESSAGE_INDEX));
096            assertEquals(event.getLoggerName(), rs.getString(DBAppender.LOGGER_NAME_INDEX));
097            assertEquals(event.getLevel().toString(), rs.getString(DBAppender.LEVEL_STRING_INDEX));
098            assertEquals(event.getThreadName(), rs.getString(DBAppender.THREAD_NAME_INDEX));
099            assertEquals(DBHelper.computeReferenceMask(event), rs.getShort(DBAppender.REFERENCE_FLAG_INDEX));
100            assertEquals(String.valueOf(diff), rs.getString(DBAppender.ARG0_INDEX));
101            StackTraceElement callerData = event.getCallerData()[0];
102            assertEquals(callerData.getFileName(), rs.getString(DBAppender.CALLER_FILENAME_INDEX));
103            assertEquals(callerData.getClassName(), rs.getString(DBAppender.CALLER_CLASS_INDEX));
104            assertEquals(callerData.getMethodName(), rs.getString(DBAppender.CALLER_METHOD_INDEX));
105        } else {
106            fail("No row was inserted in the database");
107        }
108
109        rs.close();
110        stmt.close();
111    }
112
113    @Test
114    public void testAppendThrowable() throws SQLException {
115        ILoggingEvent event = createLoggingEvent();
116        appender.append(event);
117        Statement stmt = connectionSource.getConnection().createStatement();
118        ResultSet rs = null;
119        rs = stmt.executeQuery("SELECT * FROM LOGGING_EVENT_EXCEPTION WHERE EVENT_ID=1");
120        rs.next();
121        String expected = "java.lang.Exception: test Ex";
122        String firstLine = rs.getString(3);
123        assertTrue("[" + firstLine + "] does not match [" + expected + "]", firstLine.contains(expected));
124
125        int i = 0;
126        while (rs.next()) {
127            expected = event.getThrowableProxy().getStackTraceElementProxyArray()[i].toString();
128            String st = rs.getString(3);
129            assertTrue("[" + st + "] does not match [" + expected + "]", st.contains(expected));
130            i++;
131        }
132        assertTrue(i != 0);
133
134        rs.close();
135        stmt.close();
136    }
137
138    @Test
139    public void withNullArgument() throws SQLException {
140        ILoggingEvent event = createLoggingEvent("Processing code {}; code type is {}; request date {}; record from date {}", new Object[] { 1, 2, new Date(),
141                null });
142        appender.append(event);
143
144        Statement stmt = connectionSource.getConnection().createStatement();
145        ResultSet rs = null;
146        rs = stmt.executeQuery("SELECT * FROM logging_event");
147        if (rs.next()) {
148            assertEquals(event.getTimeStamp(), rs.getLong(DBAppender.TIMESTMP_INDEX));
149            assertEquals(event.getFormattedMessage(), rs.getString(DBAppender.FORMATTED_MESSAGE_INDEX));
150        }
151    }
152
153    @Test
154    public void testContextInfo() throws SQLException {
155        loggerContext.putProperty("testKey1", "testValue1");
156        MDC.put("k" + diff, "v" + diff);
157        ILoggingEvent event = createLoggingEvent();
158
159        appender.append(event);
160
161        Statement stmt = connectionSource.getConnection().createStatement();
162        ResultSet rs = null;
163        rs = stmt.executeQuery("SELECT * FROM LOGGING_EVENT_PROPERTY WHERE EVENT_ID=1");
164        Map<String, String> map = appender.mergePropertyMaps(event);
165        int i = 0;
166        while (rs.next()) {
167            String key = rs.getString(2);
168            assertEquals(map.get(key), rs.getString(3));
169            i++;
170        }
171        assertTrue(map.size() != 0);
172        assertEquals(map.size(), i);
173        rs.close();
174        stmt.close();
175    }
176
177    @Test
178    public void testAppendMultipleEvents() throws SQLException {
179        for (int i = 0; i < 10; i++) {
180            ILoggingEvent event = createLoggingEvent();
181            appender.append(event);
182        }
183
184        Statement stmt = connectionSource.getConnection().createStatement();
185        ResultSet rs = null;
186        rs = stmt.executeQuery("SELECT * FROM logging_event");
187        int count = 0;
188        while (rs.next()) {
189            count++;
190        }
191        assertEquals(10, count);
192
193        rs.close();
194        stmt.close();
195    }
196
197    // http://jira.qos.ch/browse/LOGBACK-805
198    @Test
199    public void emptyCallerDataShouldBeHandledGracefully() {
200        LoggingEvent event = createLoggingEvent();
201        event.setCallerData(new StackTraceElement[0]);
202        appender.append(event);
203
204        event.setCallerData(new StackTraceElement[] { null });
205        appender.append(event);
206
207        checker.assertIsErrorFree();
208    }
209
210    private LoggingEvent createLoggingEvent(String msg, Object[] args) {
211        return new LoggingEvent(this.getClass().getName(), logger, Level.DEBUG, msg, new Exception("test Ex"), args);
212    }
213
214    private LoggingEvent createLoggingEvent() {
215        return createLoggingEvent("test message", new Integer[] { diff });
216    }
217
218}