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.Map;
024
025import org.apache.log4j.MDC;
026import org.junit.*;
027
028import ch.qos.logback.classic.Level;
029import ch.qos.logback.classic.Logger;
030import ch.qos.logback.classic.LoggerContext;
031import ch.qos.logback.classic.spi.ILoggingEvent;
032import ch.qos.logback.classic.spi.LoggingEvent;
033import ch.qos.logback.core.db.DriverManagerConnectionSource;
034import ch.qos.logback.core.testUtil.RandomUtil;
035import ch.qos.logback.core.util.StatusPrinter;
036
037public class DBAppenderHSQLTest {
038
039    LoggerContext lc;
040    Logger logger;
041    DBAppender appender;
042    DriverManagerConnectionSource connectionSource;
043
044    static DBAppenderHSQLTestFixture DB_APPENDER_HSQL_TEST_FIXTURE;
045    int diff = RandomUtil.getPositiveInt();
046    int existingRowCount;
047    Statement stmt;
048
049    @BeforeClass
050    public static void beforeClass() throws SQLException {
051        DB_APPENDER_HSQL_TEST_FIXTURE = new DBAppenderHSQLTestFixture();
052        DB_APPENDER_HSQL_TEST_FIXTURE.setUp();
053    }
054
055    @AfterClass
056    public static void afterClass() throws SQLException {
057        DB_APPENDER_HSQL_TEST_FIXTURE.tearDown();
058    }
059
060    @Before
061    public void setUp() throws SQLException {
062        lc = new LoggerContext();
063        lc.setName("default");
064        logger = lc.getLogger("root");
065        appender = new DBAppender();
066        appender.setName("DB");
067        appender.setContext(lc);
068        connectionSource = new DriverManagerConnectionSource();
069        connectionSource.setContext(lc);
070        connectionSource.setDriverClass(DBAppenderHSQLTestFixture.HSQLDB_DRIVER_CLASS);
071        connectionSource.setUrl(DB_APPENDER_HSQL_TEST_FIXTURE.url);
072        connectionSource.setUser(DB_APPENDER_HSQL_TEST_FIXTURE.user);
073        connectionSource.setPassword(DB_APPENDER_HSQL_TEST_FIXTURE.password);
074        connectionSource.start();
075        appender.setConnectionSource(connectionSource);
076        appender.start();
077
078        stmt = connectionSource.getConnection().createStatement();
079        existingRowCount = existingRowCount(stmt);
080
081    }
082
083    @After
084    public void tearDown() throws SQLException {
085        logger = null;
086        lc = null;
087        appender = null;
088        connectionSource = null;
089        stmt.close();
090    }
091
092    int existingRowCount(Statement stmt) throws SQLException {
093        ResultSet rs = stmt.executeQuery("SELECT count(*) FROM logging_event");
094        int result = -1;
095        if (rs.next()) {
096            result = rs.getInt(1);
097        }
098        rs.close();
099        return result;
100    }
101
102    @Test
103    public void testAppendLoggingEvent() throws SQLException {
104
105        ILoggingEvent event = createLoggingEvent();
106        appender.append(event);
107        StatusPrinter.printInCaseOfErrorsOrWarnings(lc);
108
109        ResultSet rs = null;
110        rs = stmt.executeQuery("SELECT * FROM logging_event where EVENT_ID = " + existingRowCount);
111        if (rs.next()) {
112            assertEquals(event.getTimeStamp(), rs.getLong(DBAppender.TIMESTMP_INDEX));
113            assertEquals(event.getFormattedMessage(), rs.getString(DBAppender.FORMATTED_MESSAGE_INDEX));
114            assertEquals(event.getLoggerName(), rs.getString(DBAppender.LOGGER_NAME_INDEX));
115            assertEquals(event.getLevel().toString(), rs.getString(DBAppender.LEVEL_STRING_INDEX));
116            assertEquals(event.getThreadName(), rs.getString(DBAppender.THREAD_NAME_INDEX));
117            assertEquals(DBHelper.computeReferenceMask(event), rs.getShort(DBAppender.REFERENCE_FLAG_INDEX));
118            assertEquals(String.valueOf(diff), rs.getString(DBAppender.ARG0_INDEX));
119            StackTraceElement callerData = event.getCallerData()[0];
120            assertEquals(callerData.getFileName(), rs.getString(DBAppender.CALLER_FILENAME_INDEX));
121            assertEquals(callerData.getClassName(), rs.getString(DBAppender.CALLER_CLASS_INDEX));
122            assertEquals(callerData.getMethodName(), rs.getString(DBAppender.CALLER_METHOD_INDEX));
123        } else {
124            fail("No row was inserted in the database");
125        }
126        rs.close();
127    }
128
129    @Test
130    public void testAppendThrowable() throws SQLException {
131        ILoggingEvent event = createLoggingEvent();
132        appender.append(event);
133
134        ResultSet rs = null;
135        rs = stmt.executeQuery("SELECT * FROM LOGGING_EVENT_EXCEPTION where EVENT_ID = " + existingRowCount);
136
137        rs.next();
138        String expected = "java.lang.Exception: test Ex";
139        String firstLine = rs.getString(3);
140        assertTrue("[" + firstLine + "] does not match [" + expected + "]", firstLine.contains(expected));
141
142        int i = 0;
143        while (rs.next()) {
144            expected = event.getThrowableProxy().getStackTraceElementProxyArray()[i].toString();
145            String st = rs.getString(3);
146            assertTrue("[" + st + "] does not match [" + expected + "]", st.contains(expected));
147            i++;
148        }
149        assertTrue(i != 0);
150        rs.close();
151    }
152
153    @Test
154    public void testContextInfo() throws SQLException {
155        lc.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 = " + existingRowCount);
164        Map<String, String> map = appender.mergePropertyMaps(event);
165        System.out.println("ma.size=" + map.size());
166        int i = 0;
167        while (rs.next()) {
168            String key = rs.getString(2);
169            assertEquals(map.get(key), rs.getString(3));
170            i++;
171        }
172        assertTrue(map.size() != 0);
173        assertEquals(map.size(), i);
174        rs.close();
175    }
176
177    @Test
178    public void testAppendMultipleEvents() throws SQLException {
179        int numEvents = 3;
180        for (int i = 0; i < numEvents; i++) {
181            ILoggingEvent event = createLoggingEvent();
182            appender.append(event);
183        }
184
185        Statement stmt = connectionSource.getConnection().createStatement();
186        ResultSet rs = null;
187        rs = stmt.executeQuery("SELECT * FROM logging_event WHERE EVENT_ID >=" + existingRowCount);
188        int count = 0;
189        while (rs.next()) {
190            count++;
191        }
192        assertEquals(numEvents, count);
193        rs.close();
194    }
195
196    private ILoggingEvent createLoggingEvent() {
197        return new LoggingEvent(this.getClass().getName(), logger, Level.DEBUG, "test message", new Exception("test Ex"), new Integer[] { diff });
198    }
199}