From e0150d3d0c30369059db92c4873e8ab10c02827b Mon Sep 17 00:00:00 2001 From: Matthieu Brouillard Date: Mon, 25 Jan 2021 11:55:53 +0100 Subject: [PATCH 1/6] [MNG-7083] - introduce lazy Log message evaluation Enhance org.apache.maven.plugin.logging.Log by adding lazy java.util.function.Supplier for each log level. For each level the supplier will be called only if the corresponding log level is active. Using java 8 interface default method ensures backward compatibility with other potential implementations. --- maven-plugin-api/pom.xml | 5 + .../org/apache/maven/plugin/logging/Log.java | 58 ++++++++++++ .../maven/monitor/logging/DefaultLogTest.java | 74 +++++++++++++++ .../plugin/logging/SystemStreamLogTest.java | 94 +++++++++++++++++++ 4 files changed, 231 insertions(+) create mode 100644 maven-plugin-api/src/test/java/org/apache/maven/monitor/logging/DefaultLogTest.java create mode 100644 maven-plugin-api/src/test/java/org/apache/maven/plugin/logging/SystemStreamLogTest.java diff --git a/maven-plugin-api/pom.xml b/maven-plugin-api/pom.xml index be4b99399f7d..bc292835987a 100644 --- a/maven-plugin-api/pom.xml +++ b/maven-plugin-api/pom.xml @@ -54,6 +54,11 @@ under the License. org.codehaus.plexus plexus-classworlds + + org.mockito + mockito-core + test + diff --git a/maven-plugin-api/src/main/java/org/apache/maven/plugin/logging/Log.java b/maven-plugin-api/src/main/java/org/apache/maven/plugin/logging/Log.java index 04d85bd960cc..c83f14e74bab 100644 --- a/maven-plugin-api/src/main/java/org/apache/maven/plugin/logging/Log.java +++ b/maven-plugin-api/src/main/java/org/apache/maven/plugin/logging/Log.java @@ -19,6 +19,8 @@ * under the License. */ +import java.util.function.Supplier; + /** * This interface supplies the API for providing feedback to the user from the Mojo, using standard * Maven channels.
@@ -63,6 +65,20 @@ public interface Log */ void debug( Throwable error ); + /** + * Send a message to the user in the debug error level by computing the message + * only when needed. The supplier will be called only if @see #isDebugEnabled() is true. + * + * @param messageSupplier a non null Supplier of the message to use + */ + default void debug( Supplier messageSupplier ) + { + if ( isDebugEnabled() ) + { + debug( messageSupplier.get() ); + } + } + /** * @return true if the info error level is enabled */ @@ -92,6 +108,20 @@ public interface Log */ void info( Throwable error ); + /** + * Send a message to the user in the info error level by computing the message + * only when needed. The supplier will be called only if @see #isInfoEnabled() is true. + * + * @param messageSupplier a non null Supplier of the message to use + */ + default void info( Supplier messageSupplier ) + { + if ( isInfoEnabled() ) + { + info( messageSupplier.get() ); + } + } + /** * @return true if the warn error level is enabled */ @@ -121,6 +151,20 @@ public interface Log */ void warn( Throwable error ); + /** + * Send a message to the user in the warn error level by computing the message + * only when needed. The supplier will be called only if @see #isWarnEnabled() is true. + * + * @param messageSupplier a non null Supplier of the message to use + */ + default void warn( Supplier messageSupplier ) + { + if ( isWarnEnabled() ) + { + warn( messageSupplier.get() ); + } + } + /** * @return true if the error error level is enabled */ @@ -149,4 +193,18 @@ public interface Log * @param error */ void error( Throwable error ); + + /** + * Send a message to the user in the error error level by computing the message + * only when needed. The supplier will be called only if @see #isErrorEnabled() is true. + * + * @param messageSupplier a non null Supplier of the message to use + */ + default void error( Supplier messageSupplier ) + { + if ( isErrorEnabled() ) + { + error( messageSupplier.get() ); + } + } } diff --git a/maven-plugin-api/src/test/java/org/apache/maven/monitor/logging/DefaultLogTest.java b/maven-plugin-api/src/test/java/org/apache/maven/monitor/logging/DefaultLogTest.java new file mode 100644 index 000000000000..fb552e307d6f --- /dev/null +++ b/maven-plugin-api/src/test/java/org/apache/maven/monitor/logging/DefaultLogTest.java @@ -0,0 +1,74 @@ +package org.apache.maven.monitor.logging; + +/* + * 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. + */ + +import org.apache.maven.plugin.logging.Log; +import org.codehaus.plexus.logging.Logger; +import org.junit.jupiter.api.Test; +import org.mockito.Mockito; + +import java.util.function.Supplier; + +public class DefaultLogTest +{ + private static final String EXPECTED_MESSAGE = "expected message"; + + @Test + public void testLazyMessageIsEvaluatedForActiveLogLevels() + { + Supplier messageSupplier = Mockito.mock(Supplier.class); + Mockito.when(messageSupplier.get()).thenReturn(EXPECTED_MESSAGE); + + Logger mockPlexusLogger = Mockito.mock(Logger.class); + Mockito.when(mockPlexusLogger.isDebugEnabled()).thenReturn(Boolean.TRUE); + Mockito.when(mockPlexusLogger.isInfoEnabled()).thenReturn(Boolean.TRUE); + Mockito.when(mockPlexusLogger.isWarnEnabled()).thenReturn(Boolean.TRUE); + Mockito.when(mockPlexusLogger.isErrorEnabled()).thenReturn(Boolean.TRUE); + + Log logger = new DefaultLog(mockPlexusLogger); + logger.debug(messageSupplier); + logger.info(messageSupplier); + logger.warn(messageSupplier); + logger.error(messageSupplier); + + Mockito.verify(messageSupplier, Mockito.times(4)).get(); + } + + @Test + public void testLazyMessageIsNotEvaluatedForNonActiveLogLevels() + { + Supplier messageSupplier = Mockito.mock(Supplier.class); + Mockito.when(messageSupplier.get()).thenReturn(EXPECTED_MESSAGE); + + Logger mockPlexusLogger = Mockito.mock(Logger.class); + Mockito.when(mockPlexusLogger.isDebugEnabled()).thenReturn(Boolean.FALSE); + Mockito.when(mockPlexusLogger.isInfoEnabled()).thenReturn(Boolean.FALSE); + Mockito.when(mockPlexusLogger.isWarnEnabled()).thenReturn(Boolean.FALSE); + Mockito.when(mockPlexusLogger.isErrorEnabled()).thenReturn(Boolean.FALSE); + + Log logger = new DefaultLog(mockPlexusLogger); + logger.debug(messageSupplier); + logger.info(messageSupplier); + logger.warn(messageSupplier); + logger.error(messageSupplier); + + Mockito.verify(messageSupplier, Mockito.never()).get(); + } +} diff --git a/maven-plugin-api/src/test/java/org/apache/maven/plugin/logging/SystemStreamLogTest.java b/maven-plugin-api/src/test/java/org/apache/maven/plugin/logging/SystemStreamLogTest.java new file mode 100644 index 000000000000..9dcae8f58b5d --- /dev/null +++ b/maven-plugin-api/src/test/java/org/apache/maven/plugin/logging/SystemStreamLogTest.java @@ -0,0 +1,94 @@ +package org.apache.maven.plugin.logging; + +/* + * 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. + */ + +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.mockito.Mock; +import org.mockito.Mockito; + +import java.io.PrintStream; +import java.util.function.Supplier; + +/** + * Tests for {@link SystemStreamLog} + */ +public class SystemStreamLogTest +{ + private static final String EXPECTED_MESSAGE = "expected message"; + private static PrintStream outStream; + private static PrintStream errStream; + private static PrintStream mockOut; + private static PrintStream mockErr; + + /* + * As SystemStreamLog info/warn/error log levels are active, this test checks that + * a message supplier is really called/executed when logging at those levels + */ + @Test + public void testLazyMessageIsEvaluatedForActiveLogLevels() + { + Supplier messageSupplier = Mockito.mock(Supplier.class); + Mockito.when(messageSupplier.get()).thenReturn(EXPECTED_MESSAGE); + + Log logger = new SystemStreamLog(); + logger.info(messageSupplier); + logger.warn(messageSupplier); + logger.error(messageSupplier); + + Mockito.verify(messageSupplier, Mockito.times(3)).get(); + } + + /* + * As SystemStreamLog debug log level is inactive, this test checks that + * a message supplier is not called/executed when logging at debug level + */ + @Test + public void testDebugLazyMessageIsNotEvaluated() + { + Supplier messageSupplier = Mockito.mock(Supplier.class); + Mockito.when(messageSupplier.get()).thenReturn(EXPECTED_MESSAGE); + + Log logger = new SystemStreamLog(); + logger.debug(messageSupplier); + + Mockito.verify(messageSupplier, Mockito.never()).get(); + } + + @BeforeAll + public static void initialize() + { + outStream = System.out; + errStream = System.err; + + mockOut = Mockito.mock(PrintStream.class); + System.setOut(mockOut); + mockErr = Mockito.mock(PrintStream.class); + System.setErr(mockErr); + } + + @AfterAll + public static void cleanup() + { + System.setOut(outStream); + System.setErr(errStream); + } +} From 5da3098a162279355b2c7f9583b74c65beca315f Mon Sep 17 00:00:00 2001 From: Matthieu Brouillard Date: Tue, 26 Jan 2021 14:29:13 +0100 Subject: [PATCH 2/6] enhance org.apache.maven.plugin.logging.Log, add methods with both a Supplier and a Throwable --- .../org/apache/maven/plugin/logging/Log.java | 60 +++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/maven-plugin-api/src/main/java/org/apache/maven/plugin/logging/Log.java b/maven-plugin-api/src/main/java/org/apache/maven/plugin/logging/Log.java index c83f14e74bab..785b693e49db 100644 --- a/maven-plugin-api/src/main/java/org/apache/maven/plugin/logging/Log.java +++ b/maven-plugin-api/src/main/java/org/apache/maven/plugin/logging/Log.java @@ -79,6 +79,21 @@ default void debug( Supplier messageSupplier ) } } + /** + * Send a message to the user in the debug error level by computing the message + * only when needed. The supplier will be called only if @see #isDebugEnabled() is true. + * + * @param messageSupplier a non null Supplier of the message to use + * @param error the error that occurred and for which the log applies + */ + default void debug( Supplier messageSupplier, Throwable error ) + { + if ( isDebugEnabled() ) + { + debug( messageSupplier.get(), error ); + } + } + /** * @return true if the info error level is enabled */ @@ -122,6 +137,21 @@ default void info( Supplier messageSupplier ) } } + /** + * Send a message to the user in the info error level by computing the message + * only when needed. The supplier will be called only if @see #isInfoEnabled() is true. + * + * @param messageSupplier a non null Supplier of the message to use + * @param error the error that occurred and for which the log applies + */ + default void info( Supplier messageSupplier, Throwable error ) + { + if ( isInfoEnabled() ) + { + info( messageSupplier.get(), error ); + } + } + /** * @return true if the warn error level is enabled */ @@ -165,6 +195,21 @@ default void warn( Supplier messageSupplier ) } } + /** + * Send a message to the user in the warn error level by computing the message + * only when needed. The supplier will be called only if @see #isWarnEnabled() is true. + * + * @param messageSupplier a non null Supplier of the message to use + * @param error the error that occurred and for which the log applies + */ + default void warn( Supplier messageSupplier, Throwable error ) + { + if ( isWarnEnabled() ) + { + warn( messageSupplier.get(), error ); + } + } + /** * @return true if the error error level is enabled */ @@ -207,4 +252,19 @@ default void error( Supplier messageSupplier ) error( messageSupplier.get() ); } } + + /** + * Send a message to the user in the error error level by computing the message + * only when needed. The supplier will be called only if @see #isErrorEnabled() is true. + * + * @param messageSupplier a non null Supplier of the message to use + * @param error the error that occurred and for which the log applies + */ + default void error( Supplier messageSupplier, Throwable error ) + { + if ( isErrorEnabled() ) + { + error( messageSupplier.get(), error ); + } + } } From 3da145297566b3344b299da38829d36dd18eb5e1 Mon Sep 17 00:00:00 2001 From: Matthieu Brouillard Date: Tue, 26 Jan 2021 14:33:21 +0100 Subject: [PATCH 3/6] simplification of tests in SystemStreamLogTest, do not overwrite System.out & System.err --- .../plugin/logging/SystemStreamLogTest.java | 49 ++----------------- 1 file changed, 4 insertions(+), 45 deletions(-) diff --git a/maven-plugin-api/src/test/java/org/apache/maven/plugin/logging/SystemStreamLogTest.java b/maven-plugin-api/src/test/java/org/apache/maven/plugin/logging/SystemStreamLogTest.java index 9dcae8f58b5d..d94e7b1d6b4e 100644 --- a/maven-plugin-api/src/test/java/org/apache/maven/plugin/logging/SystemStreamLogTest.java +++ b/maven-plugin-api/src/test/java/org/apache/maven/plugin/logging/SystemStreamLogTest.java @@ -19,13 +19,9 @@ * under the License. */ -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; -import org.mockito.Mock; import org.mockito.Mockito; -import java.io.PrintStream; import java.util.function.Supplier; /** @@ -34,61 +30,24 @@ public class SystemStreamLogTest { private static final String EXPECTED_MESSAGE = "expected message"; - private static PrintStream outStream; - private static PrintStream errStream; - private static PrintStream mockOut; - private static PrintStream mockErr; /* - * As SystemStreamLog info/warn/error log levels are active, this test checks that + * As SystemStreamLog log levels are hardcoded (only info/warn/error are active), this test checks that * a message supplier is really called/executed when logging at those levels */ @Test - public void testLazyMessageIsEvaluatedForActiveLogLevels() + public void testLazyMessageIsEvaluatedForActiveLogLevelsOnly() { Supplier messageSupplier = Mockito.mock(Supplier.class); Mockito.when(messageSupplier.get()).thenReturn(EXPECTED_MESSAGE); Log logger = new SystemStreamLog(); + + logger.debug(messageSupplier); logger.info(messageSupplier); logger.warn(messageSupplier); logger.error(messageSupplier); Mockito.verify(messageSupplier, Mockito.times(3)).get(); } - - /* - * As SystemStreamLog debug log level is inactive, this test checks that - * a message supplier is not called/executed when logging at debug level - */ - @Test - public void testDebugLazyMessageIsNotEvaluated() - { - Supplier messageSupplier = Mockito.mock(Supplier.class); - Mockito.when(messageSupplier.get()).thenReturn(EXPECTED_MESSAGE); - - Log logger = new SystemStreamLog(); - logger.debug(messageSupplier); - - Mockito.verify(messageSupplier, Mockito.never()).get(); - } - - @BeforeAll - public static void initialize() - { - outStream = System.out; - errStream = System.err; - - mockOut = Mockito.mock(PrintStream.class); - System.setOut(mockOut); - mockErr = Mockito.mock(PrintStream.class); - System.setErr(mockErr); - } - - @AfterAll - public static void cleanup() - { - System.setOut(outStream); - System.setErr(errStream); - } } From 0d1c623859ce820c22f51e199ca74241b20b509d Mon Sep 17 00:00:00 2001 From: Matthieu Brouillard Date: Tue, 26 Jan 2021 14:46:29 +0100 Subject: [PATCH 4/6] add tests for Log methods with both Supplier and Throwable --- .../maven/monitor/logging/DefaultLogTest.java | 18 +++++++++++++++++- .../plugin/logging/SystemStreamLogTest.java | 14 +++++++++++--- 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/maven-plugin-api/src/test/java/org/apache/maven/monitor/logging/DefaultLogTest.java b/maven-plugin-api/src/test/java/org/apache/maven/monitor/logging/DefaultLogTest.java index fb552e307d6f..894ac546fc43 100644 --- a/maven-plugin-api/src/test/java/org/apache/maven/monitor/logging/DefaultLogTest.java +++ b/maven-plugin-api/src/test/java/org/apache/maven/monitor/logging/DefaultLogTest.java @@ -35,6 +35,8 @@ public void testLazyMessageIsEvaluatedForActiveLogLevels() { Supplier messageSupplier = Mockito.mock(Supplier.class); Mockito.when(messageSupplier.get()).thenReturn(EXPECTED_MESSAGE); + + Throwable fakeError = new RuntimeException(); Logger mockPlexusLogger = Mockito.mock(Logger.class); Mockito.when(mockPlexusLogger.isDebugEnabled()).thenReturn(Boolean.TRUE); @@ -43,12 +45,18 @@ public void testLazyMessageIsEvaluatedForActiveLogLevels() Mockito.when(mockPlexusLogger.isErrorEnabled()).thenReturn(Boolean.TRUE); Log logger = new DefaultLog(mockPlexusLogger); + logger.debug(messageSupplier); logger.info(messageSupplier); logger.warn(messageSupplier); logger.error(messageSupplier); - Mockito.verify(messageSupplier, Mockito.times(4)).get(); + logger.debug(messageSupplier, fakeError); + logger.info(messageSupplier, fakeError); + logger.warn(messageSupplier, fakeError); + logger.error(messageSupplier, fakeError); + + Mockito.verify(messageSupplier, Mockito.times(8)).get(); } @Test @@ -57,6 +65,8 @@ public void testLazyMessageIsNotEvaluatedForNonActiveLogLevels() Supplier messageSupplier = Mockito.mock(Supplier.class); Mockito.when(messageSupplier.get()).thenReturn(EXPECTED_MESSAGE); + Throwable fakeError = new RuntimeException(); + Logger mockPlexusLogger = Mockito.mock(Logger.class); Mockito.when(mockPlexusLogger.isDebugEnabled()).thenReturn(Boolean.FALSE); Mockito.when(mockPlexusLogger.isInfoEnabled()).thenReturn(Boolean.FALSE); @@ -64,11 +74,17 @@ public void testLazyMessageIsNotEvaluatedForNonActiveLogLevels() Mockito.when(mockPlexusLogger.isErrorEnabled()).thenReturn(Boolean.FALSE); Log logger = new DefaultLog(mockPlexusLogger); + logger.debug(messageSupplier); logger.info(messageSupplier); logger.warn(messageSupplier); logger.error(messageSupplier); + logger.debug(messageSupplier, fakeError); + logger.info(messageSupplier, fakeError); + logger.warn(messageSupplier, fakeError); + logger.error(messageSupplier, fakeError); + Mockito.verify(messageSupplier, Mockito.never()).get(); } } diff --git a/maven-plugin-api/src/test/java/org/apache/maven/plugin/logging/SystemStreamLogTest.java b/maven-plugin-api/src/test/java/org/apache/maven/plugin/logging/SystemStreamLogTest.java index d94e7b1d6b4e..7afbb46b6c69 100644 --- a/maven-plugin-api/src/test/java/org/apache/maven/plugin/logging/SystemStreamLogTest.java +++ b/maven-plugin-api/src/test/java/org/apache/maven/plugin/logging/SystemStreamLogTest.java @@ -33,7 +33,7 @@ public class SystemStreamLogTest /* * As SystemStreamLog log levels are hardcoded (only info/warn/error are active), this test checks that - * a message supplier is really called/executed when logging at those levels + * a message supplier is really called/executed when logging at those levels. */ @Test public void testLazyMessageIsEvaluatedForActiveLogLevelsOnly() @@ -41,13 +41,21 @@ public void testLazyMessageIsEvaluatedForActiveLogLevelsOnly() Supplier messageSupplier = Mockito.mock(Supplier.class); Mockito.when(messageSupplier.get()).thenReturn(EXPECTED_MESSAGE); + Throwable fakeError = new RuntimeException(); + Log logger = new SystemStreamLog(); logger.debug(messageSupplier); logger.info(messageSupplier); logger.warn(messageSupplier); logger.error(messageSupplier); - - Mockito.verify(messageSupplier, Mockito.times(3)).get(); + + logger.debug(messageSupplier, fakeError); + logger.info(messageSupplier, fakeError); + logger.warn(messageSupplier, fakeError); + logger.error(messageSupplier, fakeError); + + // calls at debug log level should have not lead to a Supplier call + Mockito.verify(messageSupplier, Mockito.times(6)).get(); } } From b1c8ee9660426cb92976da73098e39b732ba626f Mon Sep 17 00:00:00 2001 From: Matthieu Brouillard Date: Tue, 26 Jan 2021 16:06:53 +0100 Subject: [PATCH 5/6] remove default methods from org.apache.maven.plugin.logging.Log interface introduction of an AbstractLog clas sto share default methods implementations --- .../maven/monitor/logging/DefaultLog.java | 3 +- .../maven/plugin/logging/AbstractLog.java | 116 ++++++++++++++++++ .../org/apache/maven/plugin/logging/Log.java | 64 ++-------- .../maven/plugin/logging/SystemStreamLog.java | 2 +- 4 files changed, 127 insertions(+), 58 deletions(-) create mode 100644 maven-plugin-api/src/main/java/org/apache/maven/plugin/logging/AbstractLog.java diff --git a/maven-plugin-api/src/main/java/org/apache/maven/monitor/logging/DefaultLog.java b/maven-plugin-api/src/main/java/org/apache/maven/monitor/logging/DefaultLog.java index 1ed64ecaa9e3..3242cd53d1f1 100644 --- a/maven-plugin-api/src/main/java/org/apache/maven/monitor/logging/DefaultLog.java +++ b/maven-plugin-api/src/main/java/org/apache/maven/monitor/logging/DefaultLog.java @@ -19,6 +19,7 @@ * under the License. */ +import org.apache.maven.plugin.logging.AbstractLog; import org.apache.maven.plugin.logging.Log; import org.codehaus.plexus.logging.Logger; @@ -28,7 +29,7 @@ * @deprecated Use SLF4J directly */ @Deprecated -public class DefaultLog +public class DefaultLog extends AbstractLog implements Log { diff --git a/maven-plugin-api/src/main/java/org/apache/maven/plugin/logging/AbstractLog.java b/maven-plugin-api/src/main/java/org/apache/maven/plugin/logging/AbstractLog.java new file mode 100644 index 000000000000..1ef64e197838 --- /dev/null +++ b/maven-plugin-api/src/main/java/org/apache/maven/plugin/logging/AbstractLog.java @@ -0,0 +1,116 @@ +package org.apache.maven.plugin.logging; + +/* + * 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. + */ + +import java.util.function.Supplier; + +/** + * Abstract class providing some defaults shareable implementation of some Log methods. + */ +public abstract class AbstractLog implements Log +{ + /** + * @see org.apache.maven.plugin.logging.Log#debug(Supplier) + */ + public void debug( Supplier messageSupplier ) + { + if ( isDebugEnabled() ) + { + debug( messageSupplier.get() ); + } + } + + /** + * @see org.apache.maven.plugin.logging.Log#debug(Supplier, Throwable) + */ + public void debug( Supplier messageSupplier, Throwable error ) + { + if ( isDebugEnabled() ) + { + debug( messageSupplier.get(), error ); + } + } + + /** + * @see org.apache.maven.plugin.logging.Log#info(Supplier) + */ + public void info( Supplier messageSupplier ) + { + if ( isInfoEnabled() ) + { + info( messageSupplier.get() ); + } + } + + /** + * @see org.apache.maven.plugin.logging.Log#info(Supplier, Throwable) + */ + public void info( Supplier messageSupplier, Throwable error ) + { + if ( isInfoEnabled() ) + { + info( messageSupplier.get(), error ); + } + } + + /** + * @see org.apache.maven.plugin.logging.Log#warn(Supplier) + */ + public void warn( Supplier messageSupplier ) + { + if ( isWarnEnabled() ) + { + warn( messageSupplier.get() ); + } + } + + /** + * @see org.apache.maven.plugin.logging.Log#warn(Supplier, Throwable) + */ + public void warn( Supplier messageSupplier, Throwable error ) + { + if ( isWarnEnabled() ) + { + warn( messageSupplier.get(), error ); + } + } + + /** + * @see org.apache.maven.plugin.logging.Log#error(Supplier) + */ + public void error( Supplier messageSupplier ) + { + if ( isErrorEnabled() ) + { + error( messageSupplier.get() ); + } + } + + /** + * @see org.apache.maven.plugin.logging.Log#error(Supplier, Throwable) + */ + public void error( Supplier messageSupplier, Throwable error ) + { + if ( isErrorEnabled() ) + { + error( messageSupplier.get(), error ); + } + } +} diff --git a/maven-plugin-api/src/main/java/org/apache/maven/plugin/logging/Log.java b/maven-plugin-api/src/main/java/org/apache/maven/plugin/logging/Log.java index 785b693e49db..5f33faf03bf5 100644 --- a/maven-plugin-api/src/main/java/org/apache/maven/plugin/logging/Log.java +++ b/maven-plugin-api/src/main/java/org/apache/maven/plugin/logging/Log.java @@ -71,13 +71,7 @@ public interface Log * * @param messageSupplier a non null Supplier of the message to use */ - default void debug( Supplier messageSupplier ) - { - if ( isDebugEnabled() ) - { - debug( messageSupplier.get() ); - } - } + void debug( Supplier messageSupplier ); /** * Send a message to the user in the debug error level by computing the message @@ -86,13 +80,7 @@ default void debug( Supplier messageSupplier ) * @param messageSupplier a non null Supplier of the message to use * @param error the error that occurred and for which the log applies */ - default void debug( Supplier messageSupplier, Throwable error ) - { - if ( isDebugEnabled() ) - { - debug( messageSupplier.get(), error ); - } - } + void debug( Supplier messageSupplier, Throwable error ); /** * @return true if the info error level is enabled @@ -129,13 +117,7 @@ default void debug( Supplier messageSupplier, Throwable error ) * * @param messageSupplier a non null Supplier of the message to use */ - default void info( Supplier messageSupplier ) - { - if ( isInfoEnabled() ) - { - info( messageSupplier.get() ); - } - } + void info( Supplier messageSupplier ); /** * Send a message to the user in the info error level by computing the message @@ -144,13 +126,7 @@ default void info( Supplier messageSupplier ) * @param messageSupplier a non null Supplier of the message to use * @param error the error that occurred and for which the log applies */ - default void info( Supplier messageSupplier, Throwable error ) - { - if ( isInfoEnabled() ) - { - info( messageSupplier.get(), error ); - } - } + void info( Supplier messageSupplier, Throwable error ); /** * @return true if the warn error level is enabled @@ -187,13 +163,7 @@ default void info( Supplier messageSupplier, Throwable error ) * * @param messageSupplier a non null Supplier of the message to use */ - default void warn( Supplier messageSupplier ) - { - if ( isWarnEnabled() ) - { - warn( messageSupplier.get() ); - } - } + void warn( Supplier messageSupplier ); /** * Send a message to the user in the warn error level by computing the message @@ -202,13 +172,7 @@ default void warn( Supplier messageSupplier ) * @param messageSupplier a non null Supplier of the message to use * @param error the error that occurred and for which the log applies */ - default void warn( Supplier messageSupplier, Throwable error ) - { - if ( isWarnEnabled() ) - { - warn( messageSupplier.get(), error ); - } - } + void warn( Supplier messageSupplier, Throwable error ); /** * @return true if the error error level is enabled @@ -245,13 +209,7 @@ default void warn( Supplier messageSupplier, Throwable error ) * * @param messageSupplier a non null Supplier of the message to use */ - default void error( Supplier messageSupplier ) - { - if ( isErrorEnabled() ) - { - error( messageSupplier.get() ); - } - } + void error( Supplier messageSupplier ); /** * Send a message to the user in the error error level by computing the message @@ -260,11 +218,5 @@ default void error( Supplier messageSupplier ) * @param messageSupplier a non null Supplier of the message to use * @param error the error that occurred and for which the log applies */ - default void error( Supplier messageSupplier, Throwable error ) - { - if ( isErrorEnabled() ) - { - error( messageSupplier.get(), error ); - } - } + void error( Supplier messageSupplier, Throwable error ); } diff --git a/maven-plugin-api/src/main/java/org/apache/maven/plugin/logging/SystemStreamLog.java b/maven-plugin-api/src/main/java/org/apache/maven/plugin/logging/SystemStreamLog.java index f0fc6189d57f..5b8b277fce60 100644 --- a/maven-plugin-api/src/main/java/org/apache/maven/plugin/logging/SystemStreamLog.java +++ b/maven-plugin-api/src/main/java/org/apache/maven/plugin/logging/SystemStreamLog.java @@ -30,7 +30,7 @@ * @deprecated Use SLF4J directly */ @Deprecated -public class SystemStreamLog +public class SystemStreamLog extends AbstractLog implements Log { /** From bb38289902049d0ba31b21610d3ac4197596fb23 Mon Sep 17 00:00:00 2001 From: Matthieu Brouillard Date: Tue, 26 Jan 2021 16:45:47 +0100 Subject: [PATCH 6/6] remove mockito --- maven-plugin-api/pom.xml | 5 -- .../maven/monitor/logging/DefaultLogTest.java | 32 +++------ .../maven/monitor/logging/NoOpLogger.java | 70 +++++++++++++++++++ .../plugin/logging/CountingCallsSupplier.java | 55 +++++++++++++++ .../plugin/logging/SystemStreamLogTest.java | 8 +-- 5 files changed, 138 insertions(+), 32 deletions(-) create mode 100644 maven-plugin-api/src/test/java/org/apache/maven/monitor/logging/NoOpLogger.java create mode 100644 maven-plugin-api/src/test/java/org/apache/maven/plugin/logging/CountingCallsSupplier.java diff --git a/maven-plugin-api/pom.xml b/maven-plugin-api/pom.xml index bc292835987a..be4b99399f7d 100644 --- a/maven-plugin-api/pom.xml +++ b/maven-plugin-api/pom.xml @@ -54,11 +54,6 @@ under the License. org.codehaus.plexus plexus-classworlds - - org.mockito - mockito-core - test - diff --git a/maven-plugin-api/src/test/java/org/apache/maven/monitor/logging/DefaultLogTest.java b/maven-plugin-api/src/test/java/org/apache/maven/monitor/logging/DefaultLogTest.java index 894ac546fc43..a384be1b0eae 100644 --- a/maven-plugin-api/src/test/java/org/apache/maven/monitor/logging/DefaultLogTest.java +++ b/maven-plugin-api/src/test/java/org/apache/maven/monitor/logging/DefaultLogTest.java @@ -19,12 +19,12 @@ * under the License. */ +import org.apache.maven.plugin.logging.CountingCallsSupplier; import org.apache.maven.plugin.logging.Log; import org.codehaus.plexus.logging.Logger; import org.junit.jupiter.api.Test; -import org.mockito.Mockito; -import java.util.function.Supplier; +import static org.junit.jupiter.api.Assertions.assertEquals; public class DefaultLogTest { @@ -33,18 +33,11 @@ public class DefaultLogTest @Test public void testLazyMessageIsEvaluatedForActiveLogLevels() { - Supplier messageSupplier = Mockito.mock(Supplier.class); - Mockito.when(messageSupplier.get()).thenReturn(EXPECTED_MESSAGE); + CountingCallsSupplier messageSupplier = CountingCallsSupplier.of(EXPECTED_MESSAGE); Throwable fakeError = new RuntimeException(); - Logger mockPlexusLogger = Mockito.mock(Logger.class); - Mockito.when(mockPlexusLogger.isDebugEnabled()).thenReturn(Boolean.TRUE); - Mockito.when(mockPlexusLogger.isInfoEnabled()).thenReturn(Boolean.TRUE); - Mockito.when(mockPlexusLogger.isWarnEnabled()).thenReturn(Boolean.TRUE); - Mockito.when(mockPlexusLogger.isErrorEnabled()).thenReturn(Boolean.TRUE); - - Log logger = new DefaultLog(mockPlexusLogger); + Log logger = new DefaultLog(new NoOpLogger(Logger.LEVEL_DEBUG)); logger.debug(messageSupplier); logger.info(messageSupplier); @@ -56,24 +49,18 @@ public void testLazyMessageIsEvaluatedForActiveLogLevels() logger.warn(messageSupplier, fakeError); logger.error(messageSupplier, fakeError); - Mockito.verify(messageSupplier, Mockito.times(8)).get(); + // all log calls should have lead to a supplier call + assertEquals(8, messageSupplier.getNumberOfCalls(), "wrong number of calls to the message supplier"); } @Test public void testLazyMessageIsNotEvaluatedForNonActiveLogLevels() { - Supplier messageSupplier = Mockito.mock(Supplier.class); - Mockito.when(messageSupplier.get()).thenReturn(EXPECTED_MESSAGE); + CountingCallsSupplier messageSupplier = CountingCallsSupplier.of(EXPECTED_MESSAGE); Throwable fakeError = new RuntimeException(); - Logger mockPlexusLogger = Mockito.mock(Logger.class); - Mockito.when(mockPlexusLogger.isDebugEnabled()).thenReturn(Boolean.FALSE); - Mockito.when(mockPlexusLogger.isInfoEnabled()).thenReturn(Boolean.FALSE); - Mockito.when(mockPlexusLogger.isWarnEnabled()).thenReturn(Boolean.FALSE); - Mockito.when(mockPlexusLogger.isErrorEnabled()).thenReturn(Boolean.FALSE); - - Log logger = new DefaultLog(mockPlexusLogger); + Log logger = new DefaultLog(new NoOpLogger(Logger.LEVEL_DISABLED)); logger.debug(messageSupplier); logger.info(messageSupplier); @@ -85,6 +72,7 @@ public void testLazyMessageIsNotEvaluatedForNonActiveLogLevels() logger.warn(messageSupplier, fakeError); logger.error(messageSupplier, fakeError); - Mockito.verify(messageSupplier, Mockito.never()).get(); + // no log calls should have lead to any supplier call + assertEquals(0, messageSupplier.getNumberOfCalls(), "wrong number of calls to the message supplier"); } } diff --git a/maven-plugin-api/src/test/java/org/apache/maven/monitor/logging/NoOpLogger.java b/maven-plugin-api/src/test/java/org/apache/maven/monitor/logging/NoOpLogger.java new file mode 100644 index 000000000000..515474205f7f --- /dev/null +++ b/maven-plugin-api/src/test/java/org/apache/maven/monitor/logging/NoOpLogger.java @@ -0,0 +1,70 @@ +package org.apache.maven.monitor.logging; + +/* + * 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. + */ + +import org.codehaus.plexus.logging.AbstractLogger; +import org.codehaus.plexus.logging.Logger; + +/** + * Custom implementation for tests purpose. + */ +public class NoOpLogger extends AbstractLogger + implements Logger { + + public NoOpLogger(int threshold) + { + super(threshold, "NoOp"); + } + + @Override + public void debug(String message, Throwable throwable) + { + // no-op + } + + @Override + public void info(String message, Throwable throwable) + { + // no-op + } + + @Override + public void warn(String message, Throwable throwable) + { + // no-op + } + + @Override + public void error(String message, Throwable throwable) + { + // no-op + } + + @Override + public void fatalError(String message, Throwable throwable) + { + // no-op + } + + @Override + public Logger getChildLogger(String name) { + return this; + } +} diff --git a/maven-plugin-api/src/test/java/org/apache/maven/plugin/logging/CountingCallsSupplier.java b/maven-plugin-api/src/test/java/org/apache/maven/plugin/logging/CountingCallsSupplier.java new file mode 100644 index 000000000000..b604561a73af --- /dev/null +++ b/maven-plugin-api/src/test/java/org/apache/maven/plugin/logging/CountingCallsSupplier.java @@ -0,0 +1,55 @@ +package org.apache.maven.plugin.logging; + +/* + * 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. + */ + +import java.util.concurrent.atomic.AtomicInteger; +import java.util.function.Supplier; + +/** + * A custom Supplier implementation allowing to count how many times a constant value is delivered. + * @param the type of the value to deliver + */ +public class CountingCallsSupplier implements Supplier { + private final T value; + private final AtomicInteger counter; + + private CountingCallsSupplier(T valueToSupply) + { + this.value = valueToSupply; + this.counter = new AtomicInteger(0); + } + + @Override + public T get() + { + counter.incrementAndGet(); + return value; + } + + public int getNumberOfCalls() + { + return counter.get(); + } + + public static CountingCallsSupplier of( T value ) + { + return new CountingCallsSupplier<>( value ); + } +} diff --git a/maven-plugin-api/src/test/java/org/apache/maven/plugin/logging/SystemStreamLogTest.java b/maven-plugin-api/src/test/java/org/apache/maven/plugin/logging/SystemStreamLogTest.java index 7afbb46b6c69..e38ec1728f63 100644 --- a/maven-plugin-api/src/test/java/org/apache/maven/plugin/logging/SystemStreamLogTest.java +++ b/maven-plugin-api/src/test/java/org/apache/maven/plugin/logging/SystemStreamLogTest.java @@ -20,9 +20,8 @@ */ import org.junit.jupiter.api.Test; -import org.mockito.Mockito; -import java.util.function.Supplier; +import static org.junit.jupiter.api.Assertions.assertEquals; /** * Tests for {@link SystemStreamLog} @@ -38,8 +37,7 @@ public class SystemStreamLogTest @Test public void testLazyMessageIsEvaluatedForActiveLogLevelsOnly() { - Supplier messageSupplier = Mockito.mock(Supplier.class); - Mockito.when(messageSupplier.get()).thenReturn(EXPECTED_MESSAGE); + CountingCallsSupplier messageSupplier = CountingCallsSupplier.of(EXPECTED_MESSAGE); Throwable fakeError = new RuntimeException(); @@ -56,6 +54,6 @@ public void testLazyMessageIsEvaluatedForActiveLogLevelsOnly() logger.error(messageSupplier, fakeError); // calls at debug log level should have not lead to a Supplier call - Mockito.verify(messageSupplier, Mockito.times(6)).get(); + assertEquals(6, messageSupplier.getNumberOfCalls(), "wrong number of calls to the message supplier"); } }