blob: 08f31f7fa76505f2cbc79e9418065927710f5788 [file] [log] [blame]
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.activemq.store.jdbc.adapter;
import static org.apache.log4j.Level.DEBUG;
import static org.apache.log4j.Level.WARN;
import static org.junit.Assert.assertEquals;
import static org.mockito.Answers.RETURNS_DEEP_STUBS;
import static org.mockito.Mockito.inOrder;
import static org.mockito.Mockito.when;
import java.io.IOException;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
import org.apache.activemq.store.jdbc.Statements;
import org.apache.activemq.store.jdbc.TransactionContext;
import org.apache.activemq.util.DefaultTestAppender;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.apache.log4j.spi.LoggingEvent;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InOrder;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
@RunWith(MockitoJUnitRunner.class)
public class DefaultJDBCAdapterDoCreateTablesTest {
private static final String CREATE_STATEMENT1 = "createStatement1";
private static final String CREATE_STATEMENT2 = "createStatement2";
private static final String[] CREATE_STATEMENTS = new String[] { CREATE_STATEMENT1, CREATE_STATEMENT2 };
private static final int VENDOR_CODE = 1;
private static final String SQL_STATE = "SqlState";
private static final String MY_REASON = "MyReason";
private DefaultJDBCAdapter defaultJDBCAdapter;
private List<LoggingEvent> loggingEvents = new ArrayList<>();
@Mock
private TransactionContext transactionContext;
@Mock(answer = RETURNS_DEEP_STUBS)
private Connection connection;
@Mock
private Statements statements;
@Mock
private ResultSet resultSet;
@Mock
private Statement statement1, statement2;
@Before
public void setUp() throws IOException, SQLException {
DefaultTestAppender appender = new DefaultTestAppender() {
@Override
public void doAppend(LoggingEvent event) {
loggingEvents.add(event);
}
};
Logger rootLogger = Logger.getRootLogger();
rootLogger.setLevel(Level.DEBUG);
rootLogger.addAppender(appender);
defaultJDBCAdapter = new DefaultJDBCAdapter();
defaultJDBCAdapter.statements = statements;
when(statements.getCreateSchemaStatements()).thenReturn(CREATE_STATEMENTS);
when(transactionContext.getConnection()).thenReturn(connection);
when(connection.getMetaData().getTables(null, null, this.statements.getFullMessageTableName(),new String[] { "TABLE" })).thenReturn(resultSet);
when(connection.createStatement()).thenReturn(statement1, statement2);
when(connection.getAutoCommit()).thenReturn(true);
}
@After
public void tearDown() {
loggingEvents = new ArrayList<>();
}
@Test
public void createsTheTablesWhenNoMessageTableExistsAndLogsSqlExceptionsInWarnLevel() throws IOException, SQLException {
when(resultSet.next()).thenReturn(false);
when(statement2.execute(CREATE_STATEMENT2)).thenThrow(new SQLException(MY_REASON, SQL_STATE, VENDOR_CODE));
defaultJDBCAdapter.doCreateTables(transactionContext);
InOrder inOrder = inOrder(resultSet, connection, statement1, statement2);
inOrder.verify(resultSet).next();
inOrder.verify(resultSet).close();
inOrder.verify(connection).createStatement();
inOrder.verify(statement1).execute(CREATE_STATEMENT1);
inOrder.verify(statement1).close();
inOrder.verify(connection).createStatement();
inOrder.verify(statement2).execute(CREATE_STATEMENT2);
inOrder.verify(statement2).close();
assertEquals(4, loggingEvents.size());
assertLog(0, DEBUG, "Executing SQL: " + CREATE_STATEMENT1);
assertLog(1, DEBUG, "Executing SQL: " + CREATE_STATEMENT2);
assertLog(2, WARN, "Could not create JDBC tables; they could already exist. Failure was: " + CREATE_STATEMENT2 + " Message: " + MY_REASON + " SQLState: " + SQL_STATE + " Vendor code: " + VENDOR_CODE);
assertLog(3, WARN, "Failure details: " + MY_REASON);
}
@Test
public void triesTocreateTheTablesWhenMessageTableExistsAndLogsSqlExceptionsInDebugLevel() throws SQLException, IOException {
when(resultSet.next()).thenReturn(true);
when(statement1.execute(CREATE_STATEMENT1)).thenThrow(new SQLException(MY_REASON, SQL_STATE, VENDOR_CODE));
defaultJDBCAdapter.doCreateTables(transactionContext);
InOrder inOrder = inOrder(resultSet, connection, statement1, statement2);
inOrder.verify(resultSet).next();
inOrder.verify(resultSet).close();
inOrder.verify(connection).createStatement();
inOrder.verify(statement1).execute(CREATE_STATEMENT1);
inOrder.verify(statement1).close();
inOrder.verify(connection).createStatement();
inOrder.verify(statement2).execute(CREATE_STATEMENT2);
inOrder.verify(statement2).close();
assertEquals(3, loggingEvents.size());
assertLog(0, DEBUG, "Executing SQL: " + CREATE_STATEMENT1);
assertLog(1, DEBUG, "Could not create JDBC tables; The message table already existed. Failure was: " + CREATE_STATEMENT1 + " Message: " + MY_REASON + " SQLState: " + SQL_STATE + " Vendor code: " + VENDOR_CODE);
assertLog(2, DEBUG, "Executing SQL: " + CREATE_STATEMENT2);
}
@Test
public void commitsTheTransactionWhenAutoCommitIsDisabled() throws SQLException, IOException {
when(connection.getAutoCommit()).thenReturn(false);
when(resultSet.next()).thenReturn(false);
defaultJDBCAdapter.doCreateTables(transactionContext);
InOrder inOrder = inOrder(resultSet, connection, statement1, statement2);
inOrder.verify(resultSet).next();
inOrder.verify(resultSet).close();
inOrder.verify(connection).createStatement();
inOrder.verify(statement1).execute(CREATE_STATEMENT1);
inOrder.verify(connection).commit();
inOrder.verify(statement1).close();
inOrder.verify(connection).createStatement();
inOrder.verify(statement2).execute(CREATE_STATEMENT2);
inOrder.verify(connection).commit();
inOrder.verify(statement2).close();
assertEquals(2, loggingEvents.size());
assertLog(0, DEBUG, "Executing SQL: " + CREATE_STATEMENT1);
assertLog(1, DEBUG, "Executing SQL: " + CREATE_STATEMENT2);
}
private void assertLog(int messageNumber, Level level, String message) {
LoggingEvent loggingEvent = loggingEvents.get(messageNumber);
assertEquals(level, loggingEvent.getLevel());
assertEquals(message, loggingEvent.getMessage());
}
}