From: Sébastien Lesaint Date: Mon, 20 Aug 2018 11:56:23 +0000 (+0200) Subject: SONAR-11169 add ability to verify log arguments X-Git-Tag: 7.5~573 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=bf29c23245c1d38aa5ebe38a4cb7a1ffc9173e14;p=sonarqube.git SONAR-11169 add ability to verify log arguments --- diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/utils/log/ListInterceptor.java b/sonar-plugin-api/src/main/java/org/sonar/api/utils/log/ListInterceptor.java index b5288a6ce0f..3bd9d5a6928 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/utils/log/ListInterceptor.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/utils/log/ListInterceptor.java @@ -21,55 +21,73 @@ package org.sonar.api.utils.log; import com.google.common.collect.ArrayListMultimap; import com.google.common.collect.ListMultimap; - -import javax.annotation.Nullable; - import java.util.ArrayList; import java.util.List; +import java.util.Optional; +import java.util.function.Predicate; +import java.util.stream.Collectors; +import javax.annotation.Nullable; -class ListInterceptor implements LogInterceptor { +public class ListInterceptor implements LogInterceptor { - private final List logs = new ArrayList<>(); - private final ListMultimap logsByLevel = ArrayListMultimap.create(); + private final List logs = new ArrayList<>(); + private final ListMultimap logsByLevel = ArrayListMultimap.create(); @Override public void log(LoggerLevel level, String msg) { - logs.add(msg); - logsByLevel.put(level, msg); + LogAndArguments l = new LogAndArguments(msg, msg); + add(level, l); } @Override public void log(LoggerLevel level, String msg, @Nullable Object arg) { String s = ConsoleFormatter.format(msg, arg); - logs.add(s); - logsByLevel.put(level, s); + LogAndArguments l = new LogAndArguments(s, msg, arg); + add(level, l); } @Override public void log(LoggerLevel level, String msg, @Nullable Object arg1, @Nullable Object arg2) { String s = ConsoleFormatter.format(msg, arg1, arg2); - logs.add(s); - logsByLevel.put(level, s); + LogAndArguments l = new LogAndArguments(s, msg, arg1, arg2); + add(level, l); } @Override public void log(LoggerLevel level, String msg, Object... args) { String s = ConsoleFormatter.format(msg, args); - logs.add(s); - logsByLevel.put(level, s); + LogAndArguments l = new LogAndArguments(s, msg, args); + add(level, l); } @Override public void log(LoggerLevel level, String msg, Throwable thrown) { - logs.add(msg); - logsByLevel.put(level, msg); + LogAndArguments l = new LogAndArguments(msg, msg, thrown); + add(level, l); + } + + private void add(LoggerLevel level, LogAndArguments l) { + logs.add(l); + logsByLevel.put(level, l); } public List logs() { - return logs; + return logs.stream().map(LogAndArguments::getFormattedMsg).collect(Collectors.toList()); + } + + public Optional findFirst(Predicate logPredicate) { + return logs.stream().map(LogAndArguments::getFormattedMsg).filter(logPredicate).findFirst(); } public List logs(LoggerLevel level) { + return logsByLevel.get(level).stream().map(LogAndArguments::getFormattedMsg).collect(Collectors.toList()); + } + + public List getLogs() { + return logs; + } + + public List getLogs(LoggerLevel level) { return logsByLevel.get(level); } @@ -77,4 +95,5 @@ class ListInterceptor implements LogInterceptor { logs.clear(); logsByLevel.clear(); } + } diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/utils/log/LogAndArguments.java b/sonar-plugin-api/src/main/java/org/sonar/api/utils/log/LogAndArguments.java new file mode 100644 index 00000000000..5e4ad44a45b --- /dev/null +++ b/sonar-plugin-api/src/main/java/org/sonar/api/utils/log/LogAndArguments.java @@ -0,0 +1,65 @@ +/* + * SonarQube + * Copyright (C) 2009-2018 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonar.api.utils.log; + +import java.util.Optional; +import javax.annotation.Nullable; + +public final class LogAndArguments { + private final String rawMsg; + private final Object[] args; + private final String msg; + + LogAndArguments(String msg, String rawMsg) { + this.rawMsg = rawMsg; + this.msg = msg; + this.args = null; + } + + LogAndArguments(String msg, String rawMsg, @Nullable Object arg1) { + this.rawMsg = rawMsg; + this.args = new Object[] {arg1}; + this.msg = msg; + } + + LogAndArguments(String msg, String rawMsg, @Nullable Object arg1, @Nullable Object arg2) { + this.rawMsg = rawMsg; + this.msg = msg; + this.args = new Object[] {arg1, arg2}; + } + + LogAndArguments(String msg, String rawMsg, Object... args) { + this.rawMsg = rawMsg; + this.msg = msg; + this.args = args; + } + + public String getRawMsg() { + return rawMsg; + } + + public Optional getArgs() { + return Optional.ofNullable(args); + } + + public String getFormattedMsg() { + return msg; + } +} diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/utils/log/LogTester.java b/sonar-plugin-api/src/main/java/org/sonar/api/utils/log/LogTester.java index 4d4edf256ee..a58bbe8f30c 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/utils/log/LogTester.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/utils/log/LogTester.java @@ -20,6 +20,8 @@ package org.sonar.api.utils.log; import java.util.List; +import java.util.Optional; +import java.util.function.Predicate; import org.junit.rules.ExternalResource; /** @@ -90,6 +92,10 @@ public class LogTester extends ExternalResource { return ((ListInterceptor) LogInterceptors.get()).logs(); } + public Optional findFirstLog(Predicate msgPredicate) { + return ((ListInterceptor) LogInterceptors.get()).findFirst(msgPredicate); + } + /** * Logs in chronological order (item at index 0 is the oldest one) for * a given level @@ -98,6 +104,21 @@ public class LogTester extends ExternalResource { return ((ListInterceptor) LogInterceptors.get()).logs(level); } + /** + * Logs with arguments in chronological order (item at index 0 is the oldest one) + */ + public List getLogs() { + return ((ListInterceptor) LogInterceptors.get()).getLogs(); + } + + /** + * Logs with arguments in chronological order (item at index 0 is the oldest one) for + * a given level + */ + public List getLogs(LoggerLevel level) { + return ((ListInterceptor) LogInterceptors.get()).getLogs(level); + } + public LogTester clear() { ((ListInterceptor) LogInterceptors.get()).clear(); return this; diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/utils/log/LogTesterTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/utils/log/LogTesterTest.java index 0d43ce38e31..6a459beea43 100644 --- a/sonar-plugin-api/src/test/java/org/sonar/api/utils/log/LogTesterTest.java +++ b/sonar-plugin-api/src/test/java/org/sonar/api/utils/log/LogTesterTest.java @@ -99,7 +99,7 @@ public class LogTesterTest { assertThat(touchedTrace.get()).isFalse(); assertThat(touchedDebug.get()).isTrue(); touchedDebug.set(false); - underTest.logs().clear(); + underTest.clear(); // change level to TRACE underTest.setLevel(LoggerLevel.TRACE); diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/util/ProgressReportTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/util/ProgressReportTest.java index 32a9811f5b9..6c536b0e527 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/util/ProgressReportTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/util/ProgressReportTest.java @@ -60,7 +60,7 @@ public class ProgressReportTest { underTest.message("Some message"); boolean logged = false; while (!logged) { - logged = logTester.logs().contains("Some message"); + logged = logTester.findFirstLog("Some message"::equals).isPresent(); } underTest.stop("stop"); }