/*
* Copyright (C) 2013-2017 NTT DATA Corporation
*
* Licensed 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.terasoluna.gfw.common.exception;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.fail;
import static org.mockito.Matchers.anyObject;
import static org.mockito.Matchers.argThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import java.io.FileNotFoundException;
import org.junit.Before;
import org.junit.Test;
import org.mockito.ArgumentMatcher;
import ch.qos.logback.classic.Level;
import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.classic.spi.LoggingEvent;
import ch.qos.logback.core.Appender;
public class ExceptionLoggerTest {
private ExceptionLogger testTarget;
private Appender<ILoggingEvent> mockApplicationLoggerAppender;
private Appender<ILoggingEvent> mockMonitoringLoggerAppender;
private Logger applicationLogger;
private Logger monitoringLogger;
@Before
public void setUp() throws Exception {
this.testTarget = new ExceptionLogger();
testTarget.afterPropertiesSet();
@SuppressWarnings("unchecked")
Appender<ILoggingEvent> mockApplicationLoggerAppender = mock(Appender.class);
this.mockApplicationLoggerAppender = mockApplicationLoggerAppender;
this.applicationLogger = (Logger) testTarget.getApplicationLogger();
applicationLogger.addAppender(mockApplicationLoggerAppender);
applicationLogger.setAdditive(false);
@SuppressWarnings("unchecked")
Appender<ILoggingEvent> monitoringLoggerAppender = mock(Appender.class);
this.mockMonitoringLoggerAppender = monitoringLoggerAppender;
this.monitoringLogger = (Logger) testTarget.getMonitoringLogger();
monitoringLogger.addAppender(mockMonitoringLoggerAppender);
monitoringLogger.setAdditive(false);
}
@Test
public void testFormatLogMessage_code_and_message_is_notnull() {
// do setup.
String code = "code";
String message = "message";
// do test.
String actualLogMessage = testTarget.formatLogMessage(code, message);
// do assert.
String expectedLogMessage = "[" + code + "] " + message;
assertThat(actualLogMessage, is(expectedLogMessage));
}
@Test
public void testFormatLogMessage_code_is_null() {
// do setup.
String code = null;
String message = "message";
// do test.
String actualLogMessage = testTarget.formatLogMessage(code, message);
// do assert.
String expectedLogMessage = "[UNDEFINED-CODE] " + message;
assertThat(actualLogMessage, is(expectedLogMessage));
}
@Test
public void testFormatLogMessage_code_is_empty() {
// do setup.
String code = "";
String message = "message";
// do test.
String actualLogMessage = testTarget.formatLogMessage(code, message);
// do assert.
String expectedLogMessage = "[UNDEFINED-CODE] " + message;
assertThat(actualLogMessage, is(expectedLogMessage));
}
@Test
public void testFormatLogMessage_message_is_null() {
// do setup.
String code = "code";
String message = null;
// do test.
String actualLogMessage = testTarget.formatLogMessage(code, message);
// do assert.
String expectedLogMessage = "[" + code + "] UNDEFINED-MESSAGE";
assertThat(actualLogMessage, is(expectedLogMessage));
}
@Test
public void testFormatLogMessage_message_is_empty() {
// do setup.
String code = "code";
String message = "";
// do test.
String actualLogMessage = testTarget.formatLogMessage(code, message);
// do assert.
String expectedLogMessage = "[" + code + "] UNDEFINED-MESSAGE";
assertThat(actualLogMessage, is(expectedLogMessage));
}
@Test
public void testFormatLogMessage_code_and_message_is_null() {
// do setup.
String code = null;
String message = null;
// do test.
String actualLogMessage = testTarget.formatLogMessage(code, message);
// do assert.
String expectedLogMessage = "[UNDEFINED-CODE] UNDEFINED-MESSAGE";
assertThat(actualLogMessage, is(expectedLogMessage));
}
@Test
public void testFormatLogMessage_trimMessage() {
// do setup.
testTarget.setDefaultMessage("");
String code = null;
String message = null;
// do test.
String actualLogMessage = testTarget.formatLogMessage(code, message);
// do assert.
String expectedLogMessage = "[UNDEFINED-CODE]";
assertThat(actualLogMessage, is(expectedLogMessage));
}
@Test
public void testFormatLogMessage_trimMessage_false() {
// do setup.
testTarget.setTrimLogMessage(false);
testTarget.setDefaultMessage("");
String code = null;
String message = null;
// do test.
String actualLogMessage = testTarget.formatLogMessage(code, message);
// do assert.
String expectedLogMessage = "[UNDEFINED-CODE] ";
assertThat(actualLogMessage, is(expectedLogMessage));
}
@Test
public void testSetLogMessageFormat() {
// do setup.
testTarget.setLogMessageFormat("logId:{0}\tlogMessage:{1}");
String code = "exceptionCode";
String message = "exceptionMessage";
// do test.
String actualLogMessage = testTarget.formatLogMessage(code, message);
// do assert.
String expectedLogMessage = "logId:exceptionCode\tlogMessage:exceptionMessage";
assertThat(actualLogMessage, is(expectedLogMessage));
}
@Test
public void testSetDefaultCodeAndMessage() {
// do setup.
testTarget.setDefaultCode("DEFAULT-CODE");
testTarget.setDefaultMessage("DEFAULT-MESSAGE");
String code = null;
String message = null;
// do test.
String actualLogMessage = testTarget.formatLogMessage(code, message);
// do assert.
String expectedLogMessage = "[DEFAULT-CODE] DEFAULT-MESSAGE";
assertThat(actualLogMessage, is(expectedLogMessage));
}
@Test
public void testMakeLogMessage_exceptionCodeResolver_is_notnull() {
// do setup.
Exception ex = new FileNotFoundException("occur file not found exception.");
ExceptionCodeResolver mockExceptionCodeResolver = mock(ExceptionCodeResolver.class);
when(mockExceptionCodeResolver.resolveExceptionCode(ex)).thenReturn(
"code2");
testTarget.setExceptionCodeResolver(mockExceptionCodeResolver);
// do test.
String actualLogMessage = testTarget.makeLogMessage(ex);
// do assert.
String expectedLogMessage = "[code2] occur file not found exception.";
assertThat(actualLogMessage, is(expectedLogMessage));
}
@Test
public void testMakeLogMessage_exceptionCodeResolver_is_null() {
// do setup.
Exception ex = new FileNotFoundException("occur file not found exception.");
// do test.
String actualLogMessage = testTarget.makeLogMessage(ex);
// do assert.
String expectedLogMessage = "[UNDEFINED-CODE] occur file not found exception.";
assertThat(actualLogMessage, is(expectedLogMessage));
}
@Test
public void testWarn_application_and_monitoring_is_enabled() {
// do setup.
applicationLogger.setLevel(Level.WARN);
monitoringLogger.setLevel(Level.WARN);
Exception ex = new SystemException("code01", "system error.");
ExceptionCodeResolver mockExceptionCodeResolver = mock(ExceptionCodeResolver.class);
when(mockExceptionCodeResolver.resolveExceptionCode(ex)).thenReturn(
"code01");
testTarget.setExceptionCodeResolver(mockExceptionCodeResolver);
// do test.
testTarget.warn(ex);
// do assert.
String expectedLogMessage = "[code01] system error.";
verifyLogging(expectedLogMessage, Level.WARN, ex,
mockApplicationLoggerAppender);
verifyLogging(expectedLogMessage, Level.WARN,
mockMonitoringLoggerAppender);
}
@Test
public void testWarn_application_is_enabled() {
// do setup.
applicationLogger.setLevel(Level.WARN);
monitoringLogger.setLevel(Level.ERROR);
Exception ex = new SystemException("code01", "system error.");
ExceptionCodeResolver mockExceptionCodeResolver = mock(ExceptionCodeResolver.class);
when(mockExceptionCodeResolver.resolveExceptionCode(ex)).thenReturn(
"code01");
testTarget.setExceptionCodeResolver(mockExceptionCodeResolver);
// do test.
testTarget.warn(ex);
// do assert.
String expectedLogMessage = "[code01] system error.";
verifyLogging(expectedLogMessage, Level.WARN, ex,
mockApplicationLoggerAppender);
verify(mockMonitoringLoggerAppender, times(0)).doAppend(
(ILoggingEvent) anyObject());
}
@Test
public void testWarn_monitoring_is_enabled() {
// do setup.
applicationLogger.setLevel(Level.ERROR);
monitoringLogger.setLevel(Level.WARN);
Exception ex = new SystemException("code01", "system error.");
ExceptionCodeResolver mockExceptionCodeResolver = mock(ExceptionCodeResolver.class);
when(mockExceptionCodeResolver.resolveExceptionCode(ex)).thenReturn(
"code01");
testTarget.setExceptionCodeResolver(mockExceptionCodeResolver);
// do test.
testTarget.warn(ex);
// do assert.
String expectedLogMessage = "[code01] system error.";
verify(mockApplicationLoggerAppender, times(0)).doAppend(
(ILoggingEvent) anyObject());
verifyLogging(expectedLogMessage, Level.WARN,
mockMonitoringLoggerAppender);
}
@Test
public void testWarn_application_and_monitoring_is_not_enabled() {
// do setup.
applicationLogger.setLevel(Level.ERROR);
monitoringLogger.setLevel(Level.ERROR);
Exception ex = new SystemException("code01", "system error.");
ExceptionCodeResolver mockExceptionCodeResolver = mock(ExceptionCodeResolver.class);
when(mockExceptionCodeResolver.resolveExceptionCode(ex)).thenReturn(
"code01");
testTarget.setExceptionCodeResolver(mockExceptionCodeResolver);
// do test.
testTarget.warn(ex);
// do assert.
verify(mockApplicationLoggerAppender, times(0)).doAppend(
(ILoggingEvent) anyObject());
verify(mockMonitoringLoggerAppender, times(0)).doAppend(
(ILoggingEvent) anyObject());
}
@Test
public void testError_application_and_monitoring_is_enabled() {
// do setup.
applicationLogger.setLevel(Level.ERROR);
monitoringLogger.setLevel(Level.ERROR);
Exception ex = new SystemException("code01", "system error.");
ExceptionCodeResolver mockExceptionCodeResolver = mock(ExceptionCodeResolver.class);
when(mockExceptionCodeResolver.resolveExceptionCode(ex)).thenReturn(
"code01");
testTarget.setExceptionCodeResolver(mockExceptionCodeResolver);
// do test.
testTarget.error(ex);
// do assert.
String expectedLogMessage = "[code01] system error.";
verifyLogging(expectedLogMessage, Level.ERROR, ex,
mockApplicationLoggerAppender);
verifyLogging(expectedLogMessage, Level.ERROR,
mockMonitoringLoggerAppender);
}
@Test
public void testError_application_is_enabled() {
// do setup.
applicationLogger.setLevel(Level.ERROR);
monitoringLogger.setLevel(Level.OFF);
Exception ex = new SystemException("code01", "system error.");
ExceptionCodeResolver mockExceptionCodeResolver = mock(ExceptionCodeResolver.class);
when(mockExceptionCodeResolver.resolveExceptionCode(ex)).thenReturn(
"code01");
testTarget.setExceptionCodeResolver(mockExceptionCodeResolver);
// do test.
testTarget.error(ex);
// do assert.
String expectedLogMessage = "[code01] system error.";
verifyLogging(expectedLogMessage, Level.ERROR, ex,
mockApplicationLoggerAppender);
verify(mockMonitoringLoggerAppender, times(0)).doAppend(
(ILoggingEvent) anyObject());
}
@Test
public void testError_monitoring_is_enabled() {
// do setup.
applicationLogger.setLevel(Level.OFF);
monitoringLogger.setLevel(Level.ERROR);
Exception ex = new SystemException("code01", "system error.");
ExceptionCodeResolver mockExceptionCodeResolver = mock(ExceptionCodeResolver.class);
when(mockExceptionCodeResolver.resolveExceptionCode(ex)).thenReturn(
"code01");
testTarget.setExceptionCodeResolver(mockExceptionCodeResolver);
// do test.
testTarget.error(ex);
// do assert.
String expectedLogMessage = "[code01] system error.";
verify(mockApplicationLoggerAppender, times(0)).doAppend(
(ILoggingEvent) anyObject());
verifyLogging(expectedLogMessage, Level.ERROR,
mockMonitoringLoggerAppender);
}
@Test
public void testError_application_and_monitoring_is_not_enabled() {
// do setup.
applicationLogger.setLevel(Level.OFF);
monitoringLogger.setLevel(Level.OFF);
Exception ex = new SystemException("code01", "system error.");
ExceptionCodeResolver mockExceptionCodeResolver = mock(ExceptionCodeResolver.class);
when(mockExceptionCodeResolver.resolveExceptionCode(ex)).thenReturn(
"code01");
testTarget.setExceptionCodeResolver(mockExceptionCodeResolver);
// do test.
testTarget.error(ex);
// do assert.
verify(mockApplicationLoggerAppender, times(0)).doAppend(
(ILoggingEvent) anyObject());
verify(mockMonitoringLoggerAppender, times(0)).doAppend(
(ILoggingEvent) anyObject());
}
@Test
public void testLog_defined_exceptionlevel() {
// do setup.
applicationLogger.setLevel(Level.INFO);
monitoringLogger.setLevel(Level.INFO);
Exception ex = new SystemException("i.xx", "system error.");
ExceptionLevelResolver mockExceptionCodeResolver = mock(ExceptionLevelResolver.class);
when(mockExceptionCodeResolver.resolveExceptionLevel(ex)).thenReturn(
ExceptionLevel.INFO);
testTarget.setExceptionLevelResolver(mockExceptionCodeResolver);
// do test.
testTarget.log(ex);
// do assert.
String expectedLogMessage = "[i.xx] system error.";
verifyLogging(expectedLogMessage, Level.INFO, ex,
mockApplicationLoggerAppender);
verifyLogging(expectedLogMessage, Level.INFO,
mockMonitoringLoggerAppender);
}
@Test
public void testLog_undefined_exceptionlevel() throws Exception {
// do setup.
applicationLogger.setLevel(Level.INFO);
monitoringLogger.setLevel(Level.INFO);
Exception ex = new SystemException("code01", "system error.");
ExceptionLevelResolver mockExceptionCodeResolver = mock(ExceptionLevelResolver.class);
when(mockExceptionCodeResolver.resolveExceptionLevel(ex)).thenReturn(
null);
testTarget.setExceptionLevelResolver(mockExceptionCodeResolver);
testTarget.afterPropertiesSet();
// do test.
testTarget.log(ex);
// do assert.
String expectedLogMessage = "[code01] system error.";
verifyLogging(expectedLogMessage, Level.ERROR, ex,
mockApplicationLoggerAppender);
verifyLogging(expectedLogMessage, Level.ERROR,
mockMonitoringLoggerAppender);
}
@Test
public void testInfo_application_and_monitoring_is_enabled() {
// do setup.
applicationLogger.setLevel(Level.INFO);
monitoringLogger.setLevel(Level.INFO);
Exception ex = new SystemException("code01", "system error.");
ExceptionCodeResolver mockExceptionCodeResolver = mock(ExceptionCodeResolver.class);
when(mockExceptionCodeResolver.resolveExceptionCode(ex)).thenReturn(
"code01");
testTarget.setExceptionCodeResolver(mockExceptionCodeResolver);
// do test.
testTarget.info(ex);
// do assert.
String expectedLogMessage = "[code01] system error.";
verifyLogging(expectedLogMessage, Level.INFO, ex,
mockApplicationLoggerAppender);
verifyLogging(expectedLogMessage, Level.INFO,
mockMonitoringLoggerAppender);
}
@Test
public void testInfo_application_is_enabled() {
// do setup.
applicationLogger.setLevel(Level.INFO);
monitoringLogger.setLevel(Level.OFF);
Exception ex = new SystemException("code01", "system error.");
ExceptionCodeResolver mockExceptionCodeResolver = mock(ExceptionCodeResolver.class);
when(mockExceptionCodeResolver.resolveExceptionCode(ex)).thenReturn(
"code01");
testTarget.setExceptionCodeResolver(mockExceptionCodeResolver);
// do test.
testTarget.info(ex);
// do assert.
String expectedLogMessage = "[code01] system error.";
verifyLogging(expectedLogMessage, Level.INFO, ex,
mockApplicationLoggerAppender);
verify(mockMonitoringLoggerAppender, times(0)).doAppend(
(ILoggingEvent) anyObject());
}
@Test
public void testInfo_monitoring_is_enabled() {
// do setup.
applicationLogger.setLevel(Level.OFF);
monitoringLogger.setLevel(Level.INFO);
Exception ex = new SystemException("code01", "system error.");
ExceptionCodeResolver mockExceptionCodeResolver = mock(ExceptionCodeResolver.class);
when(mockExceptionCodeResolver.resolveExceptionCode(ex)).thenReturn(
"code01");
testTarget.setExceptionCodeResolver(mockExceptionCodeResolver);
// do test.
testTarget.info(ex);
// do assert.
String expectedLogMessage = "[code01] system error.";
verify(mockApplicationLoggerAppender, times(0)).doAppend(
(ILoggingEvent) anyObject());
verifyLogging(expectedLogMessage, Level.INFO,
mockMonitoringLoggerAppender);
}
@Test
public void testInfo_application_and_monitoring_is_not_enabled() {
// do setup.
applicationLogger.setLevel(Level.OFF);
monitoringLogger.setLevel(Level.OFF);
Exception ex = new SystemException("code01", "system error.");
ExceptionCodeResolver mockExceptionCodeResolver = mock(ExceptionCodeResolver.class);
when(mockExceptionCodeResolver.resolveExceptionCode(ex)).thenReturn(
"code01");
testTarget.setExceptionCodeResolver(mockExceptionCodeResolver);
// do test.
testTarget.info(ex);
// do assert.
verify(mockApplicationLoggerAppender, times(0)).doAppend(
(ILoggingEvent) anyObject());
verify(mockMonitoringLoggerAppender, times(0)).doAppend(
(ILoggingEvent) anyObject());
}
@Test
public void testAfterPropertiesSet() throws Exception {
// do setup.
applicationLogger.setLevel(Level.INFO);
monitoringLogger.setLevel(Level.INFO);
Exception ex = new SystemException("i.code01", "system error.");
ExceptionCodeResolver mockExceptionCodeResolver = mock(ExceptionCodeResolver.class);
when(mockExceptionCodeResolver.resolveExceptionCode(ex)).thenReturn(
"i.code01");
testTarget.setExceptionCodeResolver(mockExceptionCodeResolver);
testTarget.setExceptionLevelResolver(null);
testTarget.afterPropertiesSet();
// do test.
testTarget.log(ex);
// do assert.
String expectedLogMessage = "[i.code01] system error.";
verifyLogging(expectedLogMessage, Level.INFO, ex,
mockApplicationLoggerAppender);
verifyLogging(expectedLogMessage, Level.INFO,
mockMonitoringLoggerAppender);
}
@Test
public void testExceptionLogger_default() {
// do assert.
assertThat(applicationLogger.getName(), is(testTarget.getClass()
.getName()));
assertThat(monitoringLogger.getName(), is(testTarget.getClass()
.getName()
+ ".Monitoring"));
}
@Test
public void testExceptionLogger_exceptionCodeResolver_isNull() {
// do setup.
applicationLogger.setLevel(Level.INFO);
monitoringLogger.setLevel(Level.INFO);
testTarget.setExceptionCodeResolver(null);
Exception ex = new SystemException("i.code01", "system error.");
// do test.
testTarget.log(ex);
// do assert.
String expectedLogMessage = "[UNDEFINED-CODE] system error.";
verifyLogging(expectedLogMessage, Level.INFO, ex,
mockApplicationLoggerAppender);
verifyLogging(expectedLogMessage, Level.INFO,
mockMonitoringLoggerAppender);
}
@Test
public void testExceptionLogger_LogMessageFormat_isNull() {
testTarget.setLogMessageFormat(null);
try {
testTarget.afterPropertiesSet();
fail("if logMessageFormat is null, must be occur IllegalArgumentException.");
} catch (IllegalArgumentException e) {
assertThat(
e.getMessage(),
is("logMessageFormat must have placeholder({0} and {1}). {0} is replaced with exception code. {1} is replaced with exception message. current logMessageFormat is \"null\"."));
}
}
@Test
public void testExceptionLogger_LogMessageFormat_isBlank() {
testTarget.setLogMessageFormat("");
try {
testTarget.afterPropertiesSet();
fail("if logMessageFormat is null, must be occur IllegalArgumentException.");
} catch (IllegalArgumentException e) {
assertThat(
e.getMessage(),
is("logMessageFormat must have placeholder({0} and {1}). {0} is replaced with exception code. {1} is replaced with exception message. current logMessageFormat is \"\"."));
}
}
@Test
public void testExceptionLogger_LogMessageFormat_notContainsPlaceholderOfExceptionCode() {
testTarget.setLogMessageFormat("{1}");
try {
testTarget.afterPropertiesSet();
fail("if logMessageFormat not contains placeholder({0}), must be occur IllegalArgumentException.");
} catch (IllegalArgumentException e) {
assertThat(
e.getMessage(),
is("logMessageFormat must have placeholder({0} and {1}). {0} is replaced with exception code. {1} is replaced with exception message. current logMessageFormat is \"{1}\"."));
}
}
@Test
public void testExceptionLogger_LogMessageFormat_notContainsPlaceholderOfExceptionMessage() {
testTarget.setLogMessageFormat("{0}");
try {
testTarget.afterPropertiesSet();
fail("if logMessageFormat not contains placeholder({1}), must be occur IllegalArgumentException.");
} catch (IllegalArgumentException e) {
assertThat(
e.getMessage(),
is("logMessageFormat must have placeholder({0} and {1}). {0} is replaced with exception code. {1} is replaced with exception message. current logMessageFormat is \"{0}\"."));
}
}
@Test
public void testExceptionLogger_name() {
// do test.
testTarget = new ExceptionLogger("test");
// do assert.
assertThat(testTarget.getApplicationLogger().getName(), is("test"));
assertThat(testTarget.getMonitoringLogger().getName(),
is("test.Monitoring"));
}
/**
* verify logging.
* @param expectedLogMessage expected log message.
* @param expectedLogLevel expected log level.
* @param mockAppender mock appender.
*/
private void verifyLogging(final String expectedLogMessage,
final Level expectedLogLevel,
final Appender<ILoggingEvent> mockAppender) {
verifyLogging(expectedLogMessage, expectedLogLevel, null, mockAppender);
}
/**
* verify logging.
* @param expectedLogMessage expected log message.
* @param expectedLogLevel expected log level.
* @param mockAppender mock appender.
*/
private void verifyLogging(final String expectedLogMessage,
final Level expectedLogLevel, final Exception expectedException,
final Appender<ILoggingEvent> mockAppender) {
verify(mockAppender).doAppend(
argThat(new ArgumentMatcher<LoggingEvent>() {
@Override
public boolean matches(Object argument) {
return ((LoggingEvent) argument).getFormattedMessage()
.equals(expectedLogMessage);
}
}));
verify(mockAppender).doAppend(
argThat(new ArgumentMatcher<LoggingEvent>() {
@Override
public boolean matches(Object argument) {
return expectedLogLevel
.equals(((LoggingEvent) argument).getLevel());
}
}));
verify(mockAppender).doAppend(
argThat(new ArgumentMatcher<LoggingEvent>() {
@Override
public boolean matches(Object argument) {
LoggingEvent loggingEvent = (LoggingEvent) argument;
if (expectedException == null) {
return loggingEvent.getThrowableProxy() == null;
}
if (!expectedException.getClass().getName()
.equals(loggingEvent.getThrowableProxy()
.getClassName())) {
return false;
}
if (!expectedException.getMessage().equals(
loggingEvent.getThrowableProxy().getMessage())) {
return false;
}
return true;
}
}));
}
}