From 4f94303e5fcd055de9f0ca7215aed0e4e338a9b7 Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Tue, 5 May 2020 15:27:21 -0700 Subject: [PATCH] Redirect internal j.u.l.Logger to slf4j (#371) --- agent-bootstrap/agent-bootstrap.gradle | 2 + .../auto/bootstrap/PatchLogger.java | 304 +++++- .../auto/bootstrap/PatchLoggerTest.java | 862 ++++++++++++++++++ 3 files changed, 1129 insertions(+), 39 deletions(-) create mode 100644 agent-bootstrap/src/test/java/io/opentelemetry/auto/bootstrap/PatchLoggerTest.java diff --git a/agent-bootstrap/agent-bootstrap.gradle b/agent-bootstrap/agent-bootstrap.gradle index e37ad7ed50..7ea68ebdd1 100644 --- a/agent-bootstrap/agent-bootstrap.gradle +++ b/agent-bootstrap/agent-bootstrap.gradle @@ -17,4 +17,6 @@ dependencies { // ^ Generally a bad idea for libraries, but we're shadowing. testCompile project(':testing') + testCompile group: 'org.mockito', name: 'mockito-core', version: '2.19.0' + testCompile group: 'org.assertj', name: 'assertj-core', version: '1.7.1' } diff --git a/agent-bootstrap/src/main/java/io/opentelemetry/auto/bootstrap/PatchLogger.java b/agent-bootstrap/src/main/java/io/opentelemetry/auto/bootstrap/PatchLogger.java index c31addc683..3b6d4471e2 100644 --- a/agent-bootstrap/src/main/java/io/opentelemetry/auto/bootstrap/PatchLogger.java +++ b/agent-bootstrap/src/main/java/io/opentelemetry/auto/bootstrap/PatchLogger.java @@ -15,81 +15,254 @@ */ package io.opentelemetry.auto.bootstrap; +import java.text.MessageFormat; import java.util.ResourceBundle; import java.util.logging.Level; import java.util.logging.LogRecord; /** - * Dependencies of the agent somtimes call Logger.getLogger This can have the effect of initializing - * the global logger incompatibly with the user's app. + * Dependencies of the agent sometimes call java.util.logging.Logger.getLogger(). This can have the + * effect of initializing the global LogManager incompatibly with the user's app. * - *

Shadow rewrites will redirect those calls to this class, which will return a safe logger. + *

Shadow rewrites will redirect those calls to this class, which will return a safe PatchLogger. + * + *

This also has the desired outcome of redirecting all logging to a single destination (SLF4J). */ public class PatchLogger { - private static final PatchLogger SAFE_LOGGER = new PatchLogger("agentSafeLogger", "bundle"); + + public static final String GLOBAL_LOGGER_NAME = "global"; + + public static final PatchLogger global = new PatchLogger(GLOBAL_LOGGER_NAME); + + private final org.slf4j.Logger slf4jLogger; + + private ResourceBundle resourceBundle; public static PatchLogger getLogger(final String name) { - return SAFE_LOGGER; + return new PatchLogger(name); } public static PatchLogger getLogger(final String name, final String resourceBundleName) { - return SAFE_LOGGER; + return new PatchLogger(name); } - public static PatchLogger getAnonymousLogger() { - return SAFE_LOGGER; + private PatchLogger(final String name) { + this(org.slf4j.LoggerFactory.getLogger(name)); } - public static PatchLogger getAnonymousLogger(final String resourceBundleName) { - return SAFE_LOGGER; + // visible for testing + PatchLogger(final org.slf4j.Logger logger) { + slf4jLogger = logger; } - protected PatchLogger(final String name, final String resourceBundleName) { - // super(name, resourceBundleName); + // visible for testing + org.slf4j.Logger getSlf4jLogger() { + return slf4jLogger; } - // providing a bunch of empty log methods + public String getName() { + return slf4jLogger.getName(); + } - public void log(final LogRecord record) {} + public void severe(final String msg) { + slf4jLogger.error(msg); + } - public void log(final Level level, final String msg) {} + public void warning(final String msg) { + slf4jLogger.warn(msg); + } - public void log(final Level level, final String msg, final Object param1) {} + public void info(final String msg) { + slf4jLogger.info(msg); + } - public void log(final Level level, final String msg, final Object[] params) {} + public void config(final String msg) { + slf4jLogger.info(msg); + } - public void log(final Level level, final String msg, final Throwable thrown) {} + public void fine(final String msg) { + slf4jLogger.debug(msg); + } + + public void finer(final String msg) { + slf4jLogger.trace(msg); + } + + public void finest(final String msg) { + slf4jLogger.trace(msg); + } + + public void log(final LogRecord record) { + final Level level = record.getLevel(); + if (level.intValue() >= Level.SEVERE.intValue()) { + if (slf4jLogger.isErrorEnabled()) { + slf4jLogger.error(getMessage(record), record.getThrown()); + } + } else if (level.intValue() >= Level.WARNING.intValue()) { + if (slf4jLogger.isWarnEnabled()) { + slf4jLogger.warn(getMessage(record), record.getThrown()); + } + } else if (level.intValue() >= Level.CONFIG.intValue()) { + if (slf4jLogger.isInfoEnabled()) { + slf4jLogger.info(getMessage(record), record.getThrown()); + } + } else if (level.intValue() >= Level.FINE.intValue()) { + if (slf4jLogger.isDebugEnabled()) { + slf4jLogger.debug(getMessage(record), record.getThrown()); + } + } else { + if (slf4jLogger.isTraceEnabled()) { + slf4jLogger.trace(getMessage(record), record.getThrown()); + } + } + } + + public void log(final Level level, final String msg) { + if (level.intValue() >= Level.SEVERE.intValue()) { + slf4jLogger.error(msg); + } else if (level.intValue() >= Level.WARNING.intValue()) { + slf4jLogger.warn(msg); + } else if (level.intValue() >= Level.CONFIG.intValue()) { + slf4jLogger.info(msg); + } else if (level.intValue() >= Level.FINE.intValue()) { + slf4jLogger.debug(msg); + } else { + slf4jLogger.trace(msg); + } + } + + public void log(final Level level, final String msg, final Object param1) { + if (level.intValue() >= Level.SEVERE.intValue()) { + if (slf4jLogger.isErrorEnabled()) { + slf4jLogger.error(MessageFormat.format(msg, param1)); + } + } else if (level.intValue() >= Level.WARNING.intValue()) { + if (slf4jLogger.isWarnEnabled()) { + slf4jLogger.warn(MessageFormat.format(msg, param1)); + } + } else if (level.intValue() >= Level.CONFIG.intValue()) { + if (slf4jLogger.isInfoEnabled()) { + slf4jLogger.info(MessageFormat.format(msg, param1)); + } + } else if (level.intValue() >= Level.FINE.intValue()) { + if (slf4jLogger.isDebugEnabled()) { + slf4jLogger.debug(MessageFormat.format(msg, param1)); + } + } else { + if (slf4jLogger.isTraceEnabled()) { + slf4jLogger.trace(MessageFormat.format(msg, param1)); + } + } + } + + public void log(final Level level, final String msg, final Object[] params) { + if (level.intValue() >= Level.SEVERE.intValue()) { + if (slf4jLogger.isErrorEnabled()) { + slf4jLogger.error(MessageFormat.format(msg, params)); + } + } else if (level.intValue() >= Level.WARNING.intValue()) { + if (slf4jLogger.isWarnEnabled()) { + slf4jLogger.warn(MessageFormat.format(msg, params)); + } + } else if (level.intValue() >= Level.CONFIG.intValue()) { + if (slf4jLogger.isInfoEnabled()) { + slf4jLogger.info(MessageFormat.format(msg, params)); + } + } else if (level.intValue() >= Level.FINE.intValue()) { + if (slf4jLogger.isDebugEnabled()) { + slf4jLogger.debug(MessageFormat.format(msg, params)); + } + } else { + if (slf4jLogger.isTraceEnabled()) { + slf4jLogger.trace(MessageFormat.format(msg, params)); + } + } + } + + public void log(final Level level, final String msg, final Throwable thrown) { + if (level.intValue() >= Level.SEVERE.intValue()) { + slf4jLogger.error(msg, thrown); + } else if (level.intValue() >= Level.WARNING.intValue()) { + slf4jLogger.warn(msg, thrown); + } else if (level.intValue() >= Level.CONFIG.intValue()) { + slf4jLogger.info(msg, thrown); + } else if (level.intValue() >= Level.FINE.intValue()) { + slf4jLogger.debug(msg, thrown); + } else { + slf4jLogger.trace(msg, thrown); + } + } + + public boolean isLoggable(final Level level) { + if (level.intValue() >= Level.SEVERE.intValue()) { + return slf4jLogger.isErrorEnabled(); + } else if (level.intValue() >= Level.WARNING.intValue()) { + return slf4jLogger.isWarnEnabled(); + } else if (level.intValue() >= Level.CONFIG.intValue()) { + return slf4jLogger.isInfoEnabled(); + } else if (level.intValue() >= Level.FINE.intValue()) { + return slf4jLogger.isDebugEnabled(); + } else { + return slf4jLogger.isTraceEnabled(); + } + } + + public Level getLevel() { + if (slf4jLogger.isErrorEnabled()) { + return Level.SEVERE; + } else if (slf4jLogger.isWarnEnabled()) { + return Level.WARNING; + } else if (slf4jLogger.isInfoEnabled()) { + return Level.CONFIG; + } else if (slf4jLogger.isDebugEnabled()) { + return Level.FINE; + } else if (slf4jLogger.isTraceEnabled()) { + return Level.FINEST; + } else { + return Level.OFF; + } + } public void logp( - final Level level, final String sourceClass, final String sourceMethod, final String msg) {} + final Level level, final String sourceClass, final String sourceMethod, final String msg) { + log(level, msg); + } public void logp( final Level level, final String sourceClass, final String sourceMethod, final String msg, - final Object param1) {} + final Object param1) { + log(level, msg, param1); + } public void logp( final Level level, final String sourceClass, final String sourceMethod, final String msg, - final Object[] params) {} + final Object[] params) { + log(level, msg, params); + } public void logp( final Level level, final String sourceClass, final String sourceMethod, final String msg, - final Throwable thrown) {} + final Throwable thrown) { + log(level, msg, thrown); + } public void logrb( final Level level, final String sourceClass, final String sourceMethod, final String bundleName, - final String msg) {} + final String msg) { + log(level, msg); + } public void logrb( final Level level, @@ -97,7 +270,9 @@ public class PatchLogger { final String sourceMethod, final String bundleName, final String msg, - final Object param1) {} + final Object param1) { + log(level, msg, param1); + } public void logrb( final Level level, @@ -105,7 +280,9 @@ public class PatchLogger { final String sourceMethod, final String bundleName, final String msg, - final Object[] params) {} + final Object[] params) { + log(level, msg, params); + } public void logrb( final Level level, @@ -113,7 +290,14 @@ public class PatchLogger { final String sourceMethod, final ResourceBundle bundle, final String msg, - final Object... params) {} + final Object... params) { + log(level, msg, params); + } + + public void logrb( + final Level level, final ResourceBundle bundle, final String msg, final Object... params) { + log(level, msg, params); + } public void logrb( final Level level, @@ -121,7 +305,9 @@ public class PatchLogger { final String sourceMethod, final String bundleName, final String msg, - final Throwable thrown) {} + final Throwable thrown) { + log(level, msg, thrown); + } public void logrb( final Level level, @@ -129,28 +315,68 @@ public class PatchLogger { final String sourceMethod, final ResourceBundle bundle, final String msg, - final Throwable thrown) {} + final Throwable thrown) { + log(level, msg, thrown); + } - public void severe(final String msg) {} + public void logrb( + final Level level, final ResourceBundle bundle, final String msg, final Throwable thrown) { + log(level, msg, thrown); + } - public void warning(final String msg) {} + public void entering(final String sourceClass, final String sourceMethod) {} - public void info(final String msg) {} + public void entering(final String sourceClass, final String sourceMethod, final Object param1) {} - public void config(final String msg) {} + public void entering( + final String sourceClass, final String sourceMethod, final Object[] params) {} - public void fine(final String msg) {} + public void exiting(final String sourceClass, final String sourceMethod) {} - public void finer(final String msg) {} - - public void finest(final String msg) {} + public void exiting(final String sourceClass, final String sourceMethod, final Object result) {} public void throwing( final String sourceClass, final String sourceMethod, final Throwable thrown) {} - public void setLevel(final Level newLevel) throws SecurityException {} + public ResourceBundle getResourceBundle() { + return resourceBundle; + } - public boolean isLoggable(final Level level) { - return false; + public void setResourceBundle(final ResourceBundle resourceBundle) { + this.resourceBundle = resourceBundle; + } + + public String getResourceBundleName() { + return null; + } + + public PatchLogger getParent() { + return getLogger(""); + } + + public void setParent(final PatchLogger parent) {} + + public void setLevel(final Level newLevel) {} + + public static PatchLogger getAnonymousLogger() { + return getLogger(""); + } + + public static PatchLogger getAnonymousLogger(final String resourceBundleName) { + return getLogger(""); + } + + public static final PatchLogger getGlobal() { + return global; + } + + private static String getMessage(final LogRecord record) { + final String msg = record.getMessage(); + final Object[] params = record.getParameters(); + if (params == null) { + return msg; + } else { + return MessageFormat.format(msg, params); + } } } diff --git a/agent-bootstrap/src/test/java/io/opentelemetry/auto/bootstrap/PatchLoggerTest.java b/agent-bootstrap/src/test/java/io/opentelemetry/auto/bootstrap/PatchLoggerTest.java new file mode 100644 index 0000000000..ee47b85964 --- /dev/null +++ b/agent-bootstrap/src/test/java/io/opentelemetry/auto/bootstrap/PatchLoggerTest.java @@ -0,0 +1,862 @@ +/* + * Copyright The OpenTelemetry Authors + * + * 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 io.opentelemetry.auto.bootstrap; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verifyNoMoreInteractions; +import static org.mockito.Mockito.when; + +import com.google.common.collect.Lists; +import com.google.common.collect.Sets; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.List; +import java.util.ResourceBundle; +import java.util.Set; +import java.util.logging.Level; +import lombok.Data; +import org.junit.Test; +import org.mockito.InOrder; +import org.mockito.Mockito; + +public class PatchLoggerTest { + @Test + public void testImplementsAllMethods() { + final Set patchLoggerMethods = Sets.newHashSet(); + for (final Method method : PatchLogger.class.getMethods()) { + final MethodSignature methodSignature = new MethodSignature(); + methodSignature.name = method.getName(); + for (final Class clazz : method.getParameterTypes()) { + final String parameterType = clazz.getName(); + methodSignature.parameterTypes.add( + parameterType.replaceFirst( + "io.opentelemetry.auto.bootstrap.PatchLogger", "java.util.logging.Logger")); + } + methodSignature.returnType = + method + .getReturnType() + .getName() + .replace("io.opentelemetry.auto.bootstrap.PatchLogger", "java.util.logging.Logger"); + patchLoggerMethods.add(methodSignature); + } + final Set julLoggerMethods = Sets.newHashSet(); + for (final Method method : java.util.logging.Logger.class.getMethods()) { + final String methodName = method.getName(); + if (methodName.contains("Handler") || methodName.contains("Filter")) { + continue; + } + final MethodSignature builder = new MethodSignature(); + builder.name = methodName; + final List parameterTypes = Lists.newArrayList(); + for (final Class clazz : method.getParameterTypes()) { + parameterTypes.add(clazz.getName()); + } + if (parameterTypes.contains("java.util.function.Supplier")) { + // FIXME it would be good to include Java 8 methods + continue; + } + builder.parameterTypes.addAll(parameterTypes); + builder.returnType = method.getReturnType().getName(); + julLoggerMethods.add(builder); + } + assertThat(patchLoggerMethods).containsAll(julLoggerMethods); + } + + @Test + public void testGetLogger() { + final PatchLogger logger = PatchLogger.getLogger("abc"); + assertThat(logger.getSlf4jLogger().getName()).isEqualTo("abc"); + } + + @Test + public void testGetName() { + // given + final org.slf4j.Logger slf4jLogger = mock(org.slf4j.Logger.class); + when(slf4jLogger.getName()).thenReturn("xyz"); + // when + final PatchLogger logger = new PatchLogger(slf4jLogger); + // then + assertThat(logger.getName()).isEqualTo("xyz"); + } + + @Test + public void testNormalMethods() { + // given + final org.slf4j.Logger slf4jLogger = mock(org.slf4j.Logger.class); + final PatchLogger logger = new PatchLogger(slf4jLogger); + + // when + logger.severe("ereves"); + logger.warning("gninraw"); + logger.info("ofni"); + logger.config("gifnoc"); + logger.fine("enif"); + logger.finer("renif"); + logger.finest("tsenif"); + + // then + final InOrder inOrder = Mockito.inOrder(slf4jLogger); + inOrder.verify(slf4jLogger).error("ereves"); + inOrder.verify(slf4jLogger).warn("gninraw"); + inOrder.verify(slf4jLogger).info("ofni"); + inOrder.verify(slf4jLogger).info("gifnoc"); + inOrder.verify(slf4jLogger).debug("enif"); + inOrder.verify(slf4jLogger).trace("renif"); + inOrder.verify(slf4jLogger).trace("tsenif"); + verifyNoMoreInteractions(slf4jLogger); + } + + @Test + public void testParameterizedLevelMethodsWithNoParams() { + // given + final org.slf4j.Logger slf4jLogger = mock(org.slf4j.Logger.class); + final PatchLogger logger = new PatchLogger(slf4jLogger); + + // when + logger.log(Level.SEVERE, "ereves"); + logger.log(Level.WARNING, "gninraw"); + logger.log(Level.INFO, "ofni"); + logger.log(Level.CONFIG, "gifnoc"); + logger.log(Level.FINE, "enif"); + logger.log(Level.FINER, "renif"); + logger.log(Level.FINEST, "tsenif"); + + // then + final InOrder inOrder = Mockito.inOrder(slf4jLogger); + inOrder.verify(slf4jLogger).error("ereves"); + inOrder.verify(slf4jLogger).warn("gninraw"); + inOrder.verify(slf4jLogger).info("ofni"); + inOrder.verify(slf4jLogger).info("gifnoc"); + inOrder.verify(slf4jLogger).debug("enif"); + inOrder.verify(slf4jLogger).trace("renif"); + inOrder.verify(slf4jLogger).trace("tsenif"); + verifyNoMoreInteractions(slf4jLogger); + } + + @Test + public void testParameterizedLevelMethodsWithSingleParam() { + // given + final org.slf4j.Logger slf4jLogger = mock(org.slf4j.Logger.class); + when(slf4jLogger.isTraceEnabled()).thenReturn(true); + when(slf4jLogger.isDebugEnabled()).thenReturn(true); + when(slf4jLogger.isInfoEnabled()).thenReturn(true); + when(slf4jLogger.isWarnEnabled()).thenReturn(true); + when(slf4jLogger.isErrorEnabled()).thenReturn(true); + final PatchLogger logger = new PatchLogger(slf4jLogger); + + // when + logger.log(Level.SEVERE, "ereves: {0}", "a"); + logger.log(Level.WARNING, "gninraw: {0}", "b"); + logger.log(Level.INFO, "ofni: {0}", "c"); + logger.log(Level.CONFIG, "gifnoc: {0}", "d"); + logger.log(Level.FINE, "enif: {0}", "e"); + logger.log(Level.FINER, "renif: {0}", "f"); + logger.log(Level.FINEST, "tsenif: {0}", "g"); + + // then + final InOrder inOrder = Mockito.inOrder(slf4jLogger); + inOrder.verify(slf4jLogger).isErrorEnabled(); + inOrder.verify(slf4jLogger).error("ereves: a"); + inOrder.verify(slf4jLogger).isWarnEnabled(); + inOrder.verify(slf4jLogger).warn("gninraw: b"); + inOrder.verify(slf4jLogger).isInfoEnabled(); + inOrder.verify(slf4jLogger).info("ofni: c"); + inOrder.verify(slf4jLogger).isInfoEnabled(); + inOrder.verify(slf4jLogger).info("gifnoc: d"); + inOrder.verify(slf4jLogger).isDebugEnabled(); + inOrder.verify(slf4jLogger).debug("enif: e"); + inOrder.verify(slf4jLogger).isTraceEnabled(); + inOrder.verify(slf4jLogger).trace("renif: f"); + inOrder.verify(slf4jLogger).isTraceEnabled(); + inOrder.verify(slf4jLogger).trace("tsenif: g"); + verifyNoMoreInteractions(slf4jLogger); + } + + @Test + public void testParameterizedLevelMethodsWithArrayOfParams() { + // given + final org.slf4j.Logger slf4jLogger = mock(org.slf4j.Logger.class); + when(slf4jLogger.isTraceEnabled()).thenReturn(true); + when(slf4jLogger.isDebugEnabled()).thenReturn(true); + when(slf4jLogger.isInfoEnabled()).thenReturn(true); + when(slf4jLogger.isWarnEnabled()).thenReturn(true); + when(slf4jLogger.isErrorEnabled()).thenReturn(true); + final PatchLogger logger = new PatchLogger(slf4jLogger); + + // when + logger.log(Level.SEVERE, "ereves: {0},{1}", new Object[] {"a", "b"}); + logger.log(Level.WARNING, "gninraw: {0},{1}", new Object[] {"b", "c"}); + logger.log(Level.INFO, "ofni: {0},{1}", new Object[] {"c", "d"}); + logger.log(Level.CONFIG, "gifnoc: {0},{1}", new Object[] {"d", "e"}); + logger.log(Level.FINE, "enif: {0},{1}", new Object[] {"e", "f"}); + logger.log(Level.FINER, "renif: {0},{1}", new Object[] {"f", "g"}); + logger.log(Level.FINEST, "tsenif: {0},{1}", new Object[] {"g", "h"}); + + // then + final InOrder inOrder = Mockito.inOrder(slf4jLogger); + inOrder.verify(slf4jLogger).isErrorEnabled(); + inOrder.verify(slf4jLogger).error("ereves: a,b"); + inOrder.verify(slf4jLogger).isWarnEnabled(); + inOrder.verify(slf4jLogger).warn("gninraw: b,c"); + inOrder.verify(slf4jLogger).isInfoEnabled(); + inOrder.verify(slf4jLogger).info("ofni: c,d"); + inOrder.verify(slf4jLogger).isInfoEnabled(); + inOrder.verify(slf4jLogger).info("gifnoc: d,e"); + inOrder.verify(slf4jLogger).isDebugEnabled(); + inOrder.verify(slf4jLogger).debug("enif: e,f"); + inOrder.verify(slf4jLogger).isTraceEnabled(); + inOrder.verify(slf4jLogger).trace("renif: f,g"); + inOrder.verify(slf4jLogger).isTraceEnabled(); + inOrder.verify(slf4jLogger).trace("tsenif: g,h"); + verifyNoMoreInteractions(slf4jLogger); + } + + @Test + public void testParameterizedLevelMethodsWithThrowable() { + // given + final org.slf4j.Logger slf4jLogger = mock(org.slf4j.Logger.class); + final PatchLogger logger = new PatchLogger(slf4jLogger); + final Throwable a = new Throwable(); + final Throwable b = new Throwable(); + final Throwable c = new Throwable(); + final Throwable d = new Throwable(); + final Throwable e = new Throwable(); + final Throwable f = new Throwable(); + final Throwable g = new Throwable(); + + // when + logger.log(Level.SEVERE, "ereves", a); + logger.log(Level.WARNING, "gninraw", b); + logger.log(Level.INFO, "ofni", c); + logger.log(Level.CONFIG, "gifnoc", d); + logger.log(Level.FINE, "enif", e); + logger.log(Level.FINER, "renif", f); + logger.log(Level.FINEST, "tsenif", g); + + // then + final InOrder inOrder = Mockito.inOrder(slf4jLogger); + inOrder.verify(slf4jLogger).error("ereves", a); + inOrder.verify(slf4jLogger).warn("gninraw", b); + inOrder.verify(slf4jLogger).info("ofni", c); + inOrder.verify(slf4jLogger).info("gifnoc", d); + inOrder.verify(slf4jLogger).debug("enif", e); + inOrder.verify(slf4jLogger).trace("renif", f); + inOrder.verify(slf4jLogger).trace("tsenif", g); + verifyNoMoreInteractions(slf4jLogger); + } + + @Test + public void testIsLoggableAll() { + // given + final org.slf4j.Logger slf4jLogger = mock(org.slf4j.Logger.class); + when(slf4jLogger.isTraceEnabled()).thenReturn(true); + when(slf4jLogger.isDebugEnabled()).thenReturn(true); + when(slf4jLogger.isInfoEnabled()).thenReturn(true); + when(slf4jLogger.isWarnEnabled()).thenReturn(true); + when(slf4jLogger.isErrorEnabled()).thenReturn(true); + + // when + final PatchLogger logger = new PatchLogger(slf4jLogger); + + // then + assertThat(logger.isLoggable(Level.SEVERE)).isTrue(); + assertThat(logger.isLoggable(Level.WARNING)).isTrue(); + assertThat(logger.isLoggable(Level.INFO)).isTrue(); + assertThat(logger.isLoggable(Level.CONFIG)).isTrue(); + assertThat(logger.isLoggable(Level.FINE)).isTrue(); + assertThat(logger.isLoggable(Level.FINER)).isTrue(); + assertThat(logger.isLoggable(Level.FINEST)).isTrue(); + } + + @Test + public void testIsLoggableSome() { + // given + final org.slf4j.Logger slf4jLogger = mock(org.slf4j.Logger.class); + when(slf4jLogger.isTraceEnabled()).thenReturn(false); + when(slf4jLogger.isDebugEnabled()).thenReturn(false); + when(slf4jLogger.isInfoEnabled()).thenReturn(false); + when(slf4jLogger.isWarnEnabled()).thenReturn(true); + when(slf4jLogger.isErrorEnabled()).thenReturn(true); + + // when + final PatchLogger logger = new PatchLogger(slf4jLogger); + + // then + assertThat(logger.isLoggable(Level.SEVERE)).isTrue(); + assertThat(logger.isLoggable(Level.WARNING)).isTrue(); + assertThat(logger.isLoggable(Level.INFO)).isFalse(); + assertThat(logger.isLoggable(Level.CONFIG)).isFalse(); + assertThat(logger.isLoggable(Level.FINE)).isFalse(); + assertThat(logger.isLoggable(Level.FINER)).isFalse(); + assertThat(logger.isLoggable(Level.FINEST)).isFalse(); + } + + @Test + public void testIsLoggableNone() { + // given + final org.slf4j.Logger slf4jLogger = mock(org.slf4j.Logger.class); + when(slf4jLogger.isTraceEnabled()).thenReturn(false); + when(slf4jLogger.isDebugEnabled()).thenReturn(false); + when(slf4jLogger.isInfoEnabled()).thenReturn(false); + when(slf4jLogger.isWarnEnabled()).thenReturn(false); + when(slf4jLogger.isErrorEnabled()).thenReturn(false); + + // when + final PatchLogger logger = new PatchLogger(slf4jLogger); + + // then + assertThat(logger.isLoggable(Level.SEVERE)).isFalse(); + assertThat(logger.isLoggable(Level.WARNING)).isFalse(); + assertThat(logger.isLoggable(Level.INFO)).isFalse(); + assertThat(logger.isLoggable(Level.CONFIG)).isFalse(); + assertThat(logger.isLoggable(Level.FINE)).isFalse(); + assertThat(logger.isLoggable(Level.FINER)).isFalse(); + assertThat(logger.isLoggable(Level.FINEST)).isFalse(); + } + + @Test + public void testGetLevelSevere() { + // given + final org.slf4j.Logger slf4jLogger = mock(org.slf4j.Logger.class); + when(slf4jLogger.isErrorEnabled()).thenReturn(true); + // when + final PatchLogger logger = new PatchLogger(slf4jLogger); + // then + assertThat(logger.getLevel()).isEqualTo(Level.SEVERE); + } + + @Test + public void testGetLevelWarning() { + // given + final org.slf4j.Logger slf4jLogger = mock(org.slf4j.Logger.class); + when(slf4jLogger.isWarnEnabled()).thenReturn(true); + // when + final PatchLogger logger = new PatchLogger(slf4jLogger); + // then + assertThat(logger.getLevel()).isEqualTo(Level.WARNING); + } + + @Test + public void testGetLevelConfig() { + // given + final org.slf4j.Logger slf4jLogger = mock(org.slf4j.Logger.class); + when(slf4jLogger.isInfoEnabled()).thenReturn(true); + // when + final PatchLogger logger = new PatchLogger(slf4jLogger); + // then + assertThat(logger.getLevel()).isEqualTo(Level.CONFIG); + } + + @Test + public void testGetLevelFine() { + // given + final org.slf4j.Logger slf4jLogger = mock(org.slf4j.Logger.class); + when(slf4jLogger.isDebugEnabled()).thenReturn(true); + // when + final PatchLogger logger = new PatchLogger(slf4jLogger); + // then + assertThat(logger.getLevel()).isEqualTo(Level.FINE); + } + + @Test + public void testGetLevelFinest() { + // given + final org.slf4j.Logger slf4jLogger = mock(org.slf4j.Logger.class); + when(slf4jLogger.isTraceEnabled()).thenReturn(true); + // when + final PatchLogger logger = new PatchLogger(slf4jLogger); + // then + assertThat(logger.getLevel()).isEqualTo(Level.FINEST); + } + + @Test + public void testGetLevelOff() { + // given + final org.slf4j.Logger slf4jLogger = mock(org.slf4j.Logger.class); + // when + final PatchLogger logger = new PatchLogger(slf4jLogger); + // then + assertThat(logger.getLevel()).isEqualTo(Level.OFF); + } + + @Test + public void testLogpParameterizedLevelMethodsWithNoParams() { + // given + final org.slf4j.Logger slf4jLogger = mock(org.slf4j.Logger.class); + final PatchLogger logger = new PatchLogger(slf4jLogger); + + // when + logger.logp(Level.SEVERE, null, null, "ereves"); + logger.logp(Level.WARNING, null, null, "gninraw"); + logger.logp(Level.INFO, null, null, "ofni"); + logger.logp(Level.CONFIG, null, null, "gifnoc"); + logger.logp(Level.FINE, null, null, "enif"); + logger.logp(Level.FINER, null, null, "renif"); + logger.logp(Level.FINEST, null, null, "tsenif"); + + // then + final InOrder inOrder = Mockito.inOrder(slf4jLogger); + inOrder.verify(slf4jLogger).error("ereves"); + inOrder.verify(slf4jLogger).warn("gninraw"); + inOrder.verify(slf4jLogger).info("ofni"); + inOrder.verify(slf4jLogger).info("gifnoc"); + inOrder.verify(slf4jLogger).debug("enif"); + inOrder.verify(slf4jLogger).trace("renif"); + inOrder.verify(slf4jLogger).trace("tsenif"); + verifyNoMoreInteractions(slf4jLogger); + } + + @Test + public void testLogpParameterizedLevelMethodsWithSingleParam() { + // given + final org.slf4j.Logger slf4jLogger = mock(org.slf4j.Logger.class); + when(slf4jLogger.isTraceEnabled()).thenReturn(true); + when(slf4jLogger.isDebugEnabled()).thenReturn(true); + when(slf4jLogger.isInfoEnabled()).thenReturn(true); + when(slf4jLogger.isWarnEnabled()).thenReturn(true); + when(slf4jLogger.isErrorEnabled()).thenReturn(true); + final PatchLogger logger = new PatchLogger(slf4jLogger); + + // when + logger.logp(Level.SEVERE, null, null, "ereves: {0}", "a"); + logger.logp(Level.WARNING, null, null, "gninraw: {0}", "b"); + logger.logp(Level.INFO, null, null, "ofni: {0}", "c"); + logger.logp(Level.CONFIG, null, null, "gifnoc: {0}", "d"); + logger.logp(Level.FINE, null, null, "enif: {0}", "e"); + logger.logp(Level.FINER, null, null, "renif: {0}", "f"); + logger.logp(Level.FINEST, null, null, "tsenif: {0}", "g"); + + // then + final InOrder inOrder = Mockito.inOrder(slf4jLogger); + inOrder.verify(slf4jLogger).isErrorEnabled(); + inOrder.verify(slf4jLogger).error("ereves: a"); + inOrder.verify(slf4jLogger).isWarnEnabled(); + inOrder.verify(slf4jLogger).warn("gninraw: b"); + inOrder.verify(slf4jLogger).isInfoEnabled(); + inOrder.verify(slf4jLogger).info("ofni: c"); + inOrder.verify(slf4jLogger).isInfoEnabled(); + inOrder.verify(slf4jLogger).info("gifnoc: d"); + inOrder.verify(slf4jLogger).isDebugEnabled(); + inOrder.verify(slf4jLogger).debug("enif: e"); + inOrder.verify(slf4jLogger).isTraceEnabled(); + inOrder.verify(slf4jLogger).trace("renif: f"); + inOrder.verify(slf4jLogger).isTraceEnabled(); + inOrder.verify(slf4jLogger).trace("tsenif: g"); + verifyNoMoreInteractions(slf4jLogger); + } + + @Test + public void testLogpParameterizedLevelMethodsWithArrayOfParams() { + // given + final org.slf4j.Logger slf4jLogger = mock(org.slf4j.Logger.class); + when(slf4jLogger.isTraceEnabled()).thenReturn(true); + when(slf4jLogger.isDebugEnabled()).thenReturn(true); + when(slf4jLogger.isInfoEnabled()).thenReturn(true); + when(slf4jLogger.isWarnEnabled()).thenReturn(true); + when(slf4jLogger.isErrorEnabled()).thenReturn(true); + final PatchLogger logger = new PatchLogger(slf4jLogger); + + // when + logger.logp(Level.SEVERE, null, null, "ereves: {0},{1}", new Object[] {"a", "b"}); + logger.logp(Level.WARNING, null, null, "gninraw: {0},{1}", new Object[] {"b", "c"}); + logger.logp(Level.INFO, null, null, "ofni: {0},{1}", new Object[] {"c", "d"}); + logger.logp(Level.CONFIG, null, null, "gifnoc: {0},{1}", new Object[] {"d", "e"}); + logger.logp(Level.FINE, null, null, "enif: {0},{1}", new Object[] {"e", "f"}); + logger.logp(Level.FINER, null, null, "renif: {0},{1}", new Object[] {"f", "g"}); + logger.logp(Level.FINEST, null, null, "tsenif: {0},{1}", new Object[] {"g", "h"}); + + // then + final InOrder inOrder = Mockito.inOrder(slf4jLogger); + inOrder.verify(slf4jLogger).isErrorEnabled(); + inOrder.verify(slf4jLogger).error("ereves: a,b"); + inOrder.verify(slf4jLogger).isWarnEnabled(); + inOrder.verify(slf4jLogger).warn("gninraw: b,c"); + inOrder.verify(slf4jLogger).isInfoEnabled(); + inOrder.verify(slf4jLogger).info("ofni: c,d"); + inOrder.verify(slf4jLogger).isInfoEnabled(); + inOrder.verify(slf4jLogger).info("gifnoc: d,e"); + inOrder.verify(slf4jLogger).isDebugEnabled(); + inOrder.verify(slf4jLogger).debug("enif: e,f"); + inOrder.verify(slf4jLogger).isTraceEnabled(); + inOrder.verify(slf4jLogger).trace("renif: f,g"); + inOrder.verify(slf4jLogger).isTraceEnabled(); + inOrder.verify(slf4jLogger).trace("tsenif: g,h"); + verifyNoMoreInteractions(slf4jLogger); + } + + @Test + public void testLogpParameterizedLevelMethodsWithThrowable() { + // given + final org.slf4j.Logger slf4jLogger = mock(org.slf4j.Logger.class); + final PatchLogger logger = new PatchLogger(slf4jLogger); + final Throwable a = new Throwable(); + final Throwable b = new Throwable(); + final Throwable c = new Throwable(); + final Throwable d = new Throwable(); + final Throwable e = new Throwable(); + final Throwable f = new Throwable(); + final Throwable g = new Throwable(); + + // when + logger.logp(Level.SEVERE, null, null, "ereves", a); + logger.logp(Level.WARNING, null, null, "gninraw", b); + logger.logp(Level.INFO, null, null, "ofni", c); + logger.logp(Level.CONFIG, null, null, "gifnoc", d); + logger.logp(Level.FINE, null, null, "enif", e); + logger.logp(Level.FINER, null, null, "renif", f); + logger.logp(Level.FINEST, null, null, "tsenif", g); + + // then + final InOrder inOrder = Mockito.inOrder(slf4jLogger); + inOrder.verify(slf4jLogger).error("ereves", a); + inOrder.verify(slf4jLogger).warn("gninraw", b); + inOrder.verify(slf4jLogger).info("ofni", c); + inOrder.verify(slf4jLogger).info("gifnoc", d); + inOrder.verify(slf4jLogger).debug("enif", e); + inOrder.verify(slf4jLogger).trace("renif", f); + inOrder.verify(slf4jLogger).trace("tsenif", g); + verifyNoMoreInteractions(slf4jLogger); + } + + @Test + public void testLogrbParameterizedLevelMethodsWithNoParams() { + // given + final org.slf4j.Logger slf4jLogger = mock(org.slf4j.Logger.class); + final PatchLogger logger = new PatchLogger(slf4jLogger); + + // when + logger.logrb(Level.SEVERE, null, null, null, "ereves"); + logger.logrb(Level.WARNING, null, null, null, "gninraw"); + logger.logrb(Level.INFO, null, null, null, "ofni"); + logger.logrb(Level.CONFIG, null, null, null, "gifnoc"); + logger.logrb(Level.FINE, null, null, null, "enif"); + logger.logrb(Level.FINER, null, null, null, "renif"); + logger.logrb(Level.FINEST, null, null, null, "tsenif"); + + // then + final InOrder inOrder = Mockito.inOrder(slf4jLogger); + inOrder.verify(slf4jLogger).error("ereves"); + inOrder.verify(slf4jLogger).warn("gninraw"); + inOrder.verify(slf4jLogger).info("ofni"); + inOrder.verify(slf4jLogger).info("gifnoc"); + inOrder.verify(slf4jLogger).debug("enif"); + inOrder.verify(slf4jLogger).trace("renif"); + inOrder.verify(slf4jLogger).trace("tsenif"); + verifyNoMoreInteractions(slf4jLogger); + } + + @Test + public void testLogrbParameterizedLevelMethodsWithSingleParam() { + // given + final org.slf4j.Logger slf4jLogger = mock(org.slf4j.Logger.class); + when(slf4jLogger.isTraceEnabled()).thenReturn(true); + when(slf4jLogger.isDebugEnabled()).thenReturn(true); + when(slf4jLogger.isInfoEnabled()).thenReturn(true); + when(slf4jLogger.isWarnEnabled()).thenReturn(true); + when(slf4jLogger.isErrorEnabled()).thenReturn(true); + final PatchLogger logger = new PatchLogger(slf4jLogger); + + // when + logger.logrb(Level.SEVERE, null, null, null, "ereves: {0}", "a"); + logger.logrb(Level.WARNING, null, null, null, "gninraw: {0}", "b"); + logger.logrb(Level.INFO, null, null, null, "ofni: {0}", "c"); + logger.logrb(Level.CONFIG, null, null, null, "gifnoc: {0}", "d"); + logger.logrb(Level.FINE, null, null, null, "enif: {0}", "e"); + logger.logrb(Level.FINER, null, null, null, "renif: {0}", "f"); + logger.logrb(Level.FINEST, null, null, null, "tsenif: {0}", "g"); + + // then + final InOrder inOrder = Mockito.inOrder(slf4jLogger); + inOrder.verify(slf4jLogger).isErrorEnabled(); + inOrder.verify(slf4jLogger).error("ereves: a"); + inOrder.verify(slf4jLogger).isWarnEnabled(); + inOrder.verify(slf4jLogger).warn("gninraw: b"); + inOrder.verify(slf4jLogger).isInfoEnabled(); + inOrder.verify(slf4jLogger).info("ofni: c"); + inOrder.verify(slf4jLogger).isInfoEnabled(); + inOrder.verify(slf4jLogger).info("gifnoc: d"); + inOrder.verify(slf4jLogger).isDebugEnabled(); + inOrder.verify(slf4jLogger).debug("enif: e"); + inOrder.verify(slf4jLogger).isTraceEnabled(); + inOrder.verify(slf4jLogger).trace("renif: f"); + inOrder.verify(slf4jLogger).isTraceEnabled(); + inOrder.verify(slf4jLogger).trace("tsenif: g"); + verifyNoMoreInteractions(slf4jLogger); + } + + @Test + public void testLogrbParameterizedLevelMethodsWithArrayOfParams() { + // given + final org.slf4j.Logger slf4jLogger = mock(org.slf4j.Logger.class); + when(slf4jLogger.isTraceEnabled()).thenReturn(true); + when(slf4jLogger.isDebugEnabled()).thenReturn(true); + when(slf4jLogger.isInfoEnabled()).thenReturn(true); + when(slf4jLogger.isWarnEnabled()).thenReturn(true); + when(slf4jLogger.isErrorEnabled()).thenReturn(true); + final PatchLogger logger = new PatchLogger(slf4jLogger); + + // when + logger.logrb( + Level.SEVERE, null, null, (String) null, "ereves: {0},{1}", new Object[] {"a", "b"}); + logger.logrb( + Level.WARNING, null, null, (String) null, "gninraw: {0},{1}", new Object[] {"b", "c"}); + logger.logrb(Level.INFO, null, null, (String) null, "ofni: {0},{1}", new Object[] {"c", "d"}); + logger.logrb( + Level.CONFIG, null, null, (String) null, "gifnoc: {0},{1}", new Object[] {"d", "e"}); + logger.logrb(Level.FINE, null, null, (String) null, "enif: {0},{1}", new Object[] {"e", "f"}); + logger.logrb(Level.FINER, null, null, (String) null, "renif: {0},{1}", new Object[] {"f", "g"}); + logger.logrb( + Level.FINEST, null, null, (String) null, "tsenif: {0},{1}", new Object[] {"g", "h"}); + + // then + final InOrder inOrder = Mockito.inOrder(slf4jLogger); + inOrder.verify(slf4jLogger).isErrorEnabled(); + inOrder.verify(slf4jLogger).error("ereves: a,b"); + inOrder.verify(slf4jLogger).isWarnEnabled(); + inOrder.verify(slf4jLogger).warn("gninraw: b,c"); + inOrder.verify(slf4jLogger).isInfoEnabled(); + inOrder.verify(slf4jLogger).info("ofni: c,d"); + inOrder.verify(slf4jLogger).isInfoEnabled(); + inOrder.verify(slf4jLogger).info("gifnoc: d,e"); + inOrder.verify(slf4jLogger).isDebugEnabled(); + inOrder.verify(slf4jLogger).debug("enif: e,f"); + inOrder.verify(slf4jLogger).isTraceEnabled(); + inOrder.verify(slf4jLogger).trace("renif: f,g"); + inOrder.verify(slf4jLogger).isTraceEnabled(); + inOrder.verify(slf4jLogger).trace("tsenif: g,h"); + verifyNoMoreInteractions(slf4jLogger); + } + + @Test + public void testLogrbParameterizedLevelMethodsWithVarArgsOfParams() { + // given + final org.slf4j.Logger slf4jLogger = mock(org.slf4j.Logger.class); + when(slf4jLogger.isTraceEnabled()).thenReturn(true); + when(slf4jLogger.isDebugEnabled()).thenReturn(true); + when(slf4jLogger.isInfoEnabled()).thenReturn(true); + when(slf4jLogger.isWarnEnabled()).thenReturn(true); + when(slf4jLogger.isErrorEnabled()).thenReturn(true); + final PatchLogger logger = new PatchLogger(slf4jLogger); + + // when + logger.logrb(Level.SEVERE, (String) null, null, null, "ereves: {0},{1}", "a", "b"); + logger.logrb(Level.WARNING, (String) null, null, null, "gninraw: {0},{1}", "b", "c"); + logger.logrb(Level.INFO, (String) null, null, null, "ofni: {0},{1}", "c", "d"); + logger.logrb(Level.CONFIG, (String) null, null, null, "gifnoc: {0},{1}", "d", "e"); + logger.logrb(Level.FINE, (String) null, null, null, "enif: {0},{1}", "e", "f"); + logger.logrb(Level.FINER, (String) null, null, null, "renif: {0},{1}", "f", "g"); + logger.logrb(Level.FINEST, (String) null, null, null, "tsenif: {0},{1}", "g", "h"); + + // then + final InOrder inOrder = Mockito.inOrder(slf4jLogger); + inOrder.verify(slf4jLogger).isErrorEnabled(); + inOrder.verify(slf4jLogger).error("ereves: a,b"); + inOrder.verify(slf4jLogger).isWarnEnabled(); + inOrder.verify(slf4jLogger).warn("gninraw: b,c"); + inOrder.verify(slf4jLogger).isInfoEnabled(); + inOrder.verify(slf4jLogger).info("ofni: c,d"); + inOrder.verify(slf4jLogger).isInfoEnabled(); + inOrder.verify(slf4jLogger).info("gifnoc: d,e"); + inOrder.verify(slf4jLogger).isDebugEnabled(); + inOrder.verify(slf4jLogger).debug("enif: e,f"); + inOrder.verify(slf4jLogger).isTraceEnabled(); + inOrder.verify(slf4jLogger).trace("renif: f,g"); + inOrder.verify(slf4jLogger).isTraceEnabled(); + inOrder.verify(slf4jLogger).trace("tsenif: g,h"); + verifyNoMoreInteractions(slf4jLogger); + } + + @Test + public void testLogrbParameterizedLevelMethodsWithVarArgsOfParams2() { + // given + final org.slf4j.Logger slf4jLogger = mock(org.slf4j.Logger.class); + when(slf4jLogger.isTraceEnabled()).thenReturn(true); + when(slf4jLogger.isDebugEnabled()).thenReturn(true); + when(slf4jLogger.isInfoEnabled()).thenReturn(true); + when(slf4jLogger.isWarnEnabled()).thenReturn(true); + when(slf4jLogger.isErrorEnabled()).thenReturn(true); + final PatchLogger logger = new PatchLogger(slf4jLogger); + + // when + logger.logrb(Level.SEVERE, (ResourceBundle) null, "ereves: {0},{1}", "a", "b"); + logger.logrb(Level.WARNING, (ResourceBundle) null, "gninraw: {0},{1}", "b", "c"); + logger.logrb(Level.INFO, (ResourceBundle) null, "ofni: {0},{1}", "c", "d"); + logger.logrb(Level.CONFIG, (ResourceBundle) null, "gifnoc: {0},{1}", "d", "e"); + logger.logrb(Level.FINE, (ResourceBundle) null, "enif: {0},{1}", "e", "f"); + logger.logrb(Level.FINER, (ResourceBundle) null, "renif: {0},{1}", "f", "g"); + logger.logrb(Level.FINEST, (ResourceBundle) null, "tsenif: {0},{1}", "g", "h"); + + // then + final InOrder inOrder = Mockito.inOrder(slf4jLogger); + inOrder.verify(slf4jLogger).isErrorEnabled(); + inOrder.verify(slf4jLogger).error("ereves: a,b"); + inOrder.verify(slf4jLogger).isWarnEnabled(); + inOrder.verify(slf4jLogger).warn("gninraw: b,c"); + inOrder.verify(slf4jLogger).isInfoEnabled(); + inOrder.verify(slf4jLogger).info("ofni: c,d"); + inOrder.verify(slf4jLogger).isInfoEnabled(); + inOrder.verify(slf4jLogger).info("gifnoc: d,e"); + inOrder.verify(slf4jLogger).isDebugEnabled(); + inOrder.verify(slf4jLogger).debug("enif: e,f"); + inOrder.verify(slf4jLogger).isTraceEnabled(); + inOrder.verify(slf4jLogger).trace("renif: f,g"); + inOrder.verify(slf4jLogger).isTraceEnabled(); + inOrder.verify(slf4jLogger).trace("tsenif: g,h"); + verifyNoMoreInteractions(slf4jLogger); + } + + @Test + public void testLogrbParameterizedLevelMethodsWithThrowable() { + // given + final org.slf4j.Logger slf4jLogger = mock(org.slf4j.Logger.class); + final PatchLogger logger = new PatchLogger(slf4jLogger); + final Throwable a = new Throwable(); + final Throwable b = new Throwable(); + final Throwable c = new Throwable(); + final Throwable d = new Throwable(); + final Throwable e = new Throwable(); + final Throwable f = new Throwable(); + final Throwable g = new Throwable(); + + // when + logger.logrb(Level.SEVERE, null, null, (String) null, "ereves", a); + logger.logrb(Level.WARNING, null, null, (String) null, "gninraw", b); + logger.logrb(Level.INFO, null, null, (String) null, "ofni", c); + logger.logrb(Level.CONFIG, null, null, (String) null, "gifnoc", d); + logger.logrb(Level.FINE, null, null, (String) null, "enif", e); + logger.logrb(Level.FINER, null, null, (String) null, "renif", f); + logger.logrb(Level.FINEST, null, null, (String) null, "tsenif", g); + + // then + final InOrder inOrder = Mockito.inOrder(slf4jLogger); + inOrder.verify(slf4jLogger).error("ereves", a); + inOrder.verify(slf4jLogger).warn("gninraw", b); + inOrder.verify(slf4jLogger).info("ofni", c); + inOrder.verify(slf4jLogger).info("gifnoc", d); + inOrder.verify(slf4jLogger).debug("enif", e); + inOrder.verify(slf4jLogger).trace("renif", f); + inOrder.verify(slf4jLogger).trace("tsenif", g); + verifyNoMoreInteractions(slf4jLogger); + } + + @Test + public void testLogrbParameterizedLevelMethodsWithThrowable2() { + // given + final org.slf4j.Logger slf4jLogger = mock(org.slf4j.Logger.class); + final PatchLogger logger = new PatchLogger(slf4jLogger); + final Throwable a = new Throwable(); + final Throwable b = new Throwable(); + final Throwable c = new Throwable(); + final Throwable d = new Throwable(); + final Throwable e = new Throwable(); + final Throwable f = new Throwable(); + final Throwable g = new Throwable(); + + // when + logger.logrb(Level.SEVERE, null, null, (ResourceBundle) null, "ereves", a); + logger.logrb(Level.WARNING, null, null, (ResourceBundle) null, "gninraw", b); + logger.logrb(Level.INFO, null, null, (ResourceBundle) null, "ofni", c); + logger.logrb(Level.CONFIG, null, null, (ResourceBundle) null, "gifnoc", d); + logger.logrb(Level.FINE, null, null, (ResourceBundle) null, "enif", e); + logger.logrb(Level.FINER, null, null, (ResourceBundle) null, "renif", f); + logger.logrb(Level.FINEST, null, null, (ResourceBundle) null, "tsenif", g); + + // then + final InOrder inOrder = Mockito.inOrder(slf4jLogger); + inOrder.verify(slf4jLogger).error("ereves", a); + inOrder.verify(slf4jLogger).warn("gninraw", b); + inOrder.verify(slf4jLogger).info("ofni", c); + inOrder.verify(slf4jLogger).info("gifnoc", d); + inOrder.verify(slf4jLogger).debug("enif", e); + inOrder.verify(slf4jLogger).trace("renif", f); + inOrder.verify(slf4jLogger).trace("tsenif", g); + verifyNoMoreInteractions(slf4jLogger); + } + + @Test + public void testLogrbParameterizedLevelMethodsWithResourceBundleObjectAndThrowable() { + // given + final org.slf4j.Logger slf4jLogger = mock(org.slf4j.Logger.class); + final PatchLogger logger = new PatchLogger(slf4jLogger); + final Throwable a = new Throwable(); + final Throwable b = new Throwable(); + final Throwable c = new Throwable(); + final Throwable d = new Throwable(); + final Throwable e = new Throwable(); + final Throwable f = new Throwable(); + final Throwable g = new Throwable(); + + // when + logger.logrb(Level.SEVERE, null, null, (ResourceBundle) null, "ereves", a); + logger.logrb(Level.WARNING, null, null, (ResourceBundle) null, "gninraw", b); + logger.logrb(Level.INFO, null, null, (ResourceBundle) null, "ofni", c); + logger.logrb(Level.CONFIG, null, null, (ResourceBundle) null, "gifnoc", d); + logger.logrb(Level.FINE, null, null, (ResourceBundle) null, "enif", e); + logger.logrb(Level.FINER, null, null, (ResourceBundle) null, "renif", f); + logger.logrb(Level.FINEST, null, null, (ResourceBundle) null, "tsenif", g); + + // then + final InOrder inOrder = Mockito.inOrder(slf4jLogger); + inOrder.verify(slf4jLogger).error("ereves", a); + inOrder.verify(slf4jLogger).warn("gninraw", b); + inOrder.verify(slf4jLogger).info("ofni", c); + inOrder.verify(slf4jLogger).info("gifnoc", d); + inOrder.verify(slf4jLogger).debug("enif", e); + inOrder.verify(slf4jLogger).trace("renif", f); + inOrder.verify(slf4jLogger).trace("tsenif", g); + verifyNoMoreInteractions(slf4jLogger); + } + + @Test + public void testEnteringExitingThrowingMethods() { + // given + final org.slf4j.Logger slf4jLogger = mock(org.slf4j.Logger.class); + final PatchLogger logger = new PatchLogger(slf4jLogger); + + // when + logger.entering(null, null); + logger.entering(null, null, new Object()); + logger.entering(null, null, new Object[0]); + logger.exiting(null, null); + logger.exiting(null, null, new Object()); + logger.throwing(null, null, null); + + // then + verifyNoMoreInteractions(slf4jLogger); + } + + @Test + public void testResourceBundle() { + // given + final org.slf4j.Logger slf4jLogger = mock(org.slf4j.Logger.class); + + // when + final PatchLogger logger = new PatchLogger(slf4jLogger); + + // then + assertThat(logger.getResourceBundle()).isNull(); + assertThat(logger.getResourceBundleName()).isNull(); + verifyNoMoreInteractions(slf4jLogger); + } + + @Data + static class MethodSignature { + String name; + List parameterTypes = new ArrayList<>(); + String returnType; + } +}