From f5eb0e8bd4788cbd731b6dbb93b566065ce0c639 Mon Sep 17 00:00:00 2001 From: Jesse Glick Date: Tue, 2 Apr 2019 12:57:35 -0400 Subject: [PATCH 1/2] Added JenkinsRule.showSlaveLogs utility. --- pom.xml | 3 +- .../org/jvnet/hudson/test/JenkinsRule.java | 49 +++++++++++++++++++ .../org/jvnet/hudson/test/LoggerRule.java | 5 ++ 3 files changed, 56 insertions(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index b3c177720..3900f7b64 100644 --- a/pom.xml +++ b/pom.xml @@ -28,7 +28,8 @@ THE SOFTWARE. org.jenkins-ci jenkins - 1.49 + 1.51 + org.jenkins-ci.main diff --git a/src/main/java/org/jvnet/hudson/test/JenkinsRule.java b/src/main/java/org/jvnet/hudson/test/JenkinsRule.java index 9641f2707..a5a1433fb 100644 --- a/src/main/java/org/jvnet/hudson/test/JenkinsRule.java +++ b/src/main/java/org/jvnet/hudson/test/JenkinsRule.java @@ -223,8 +223,10 @@ import java.nio.channels.ClosedByInterruptException; import java.util.concurrent.ExecutionException; import java.util.logging.ConsoleHandler; +import java.util.logging.Formatter; import java.util.logging.Handler; import jenkins.model.ParameterizedJobMixIn; +import jenkins.security.MasterToSlaveCallable; import org.hamcrest.core.IsInstanceOf; import org.junit.rules.DisableOnDebug; import org.junit.rules.Timeout; @@ -988,6 +990,53 @@ public void waitOnline(Slave s) throws Exception { } } + /** + * Same as {@link #showSlaveLogs(Slave, Map)} but taking a preconfigured list of loggers as a convenience. + */ + public void showSlaveLogs(Slave s, LoggerRule loggerRule) throws Exception { + showSlaveLogs(s, loggerRule.getRecordedLevels()); + } + + /** + * Forward agent logs to standard error of the test process. + * Otherwise log messages would be sent only to {@link Computer#getLogText} etc., + * or discarded entirely (if below {@link Level#INFO}). + * @param s an online agent + * @param loggers {@link Logger#getName} tied to log level + */ + public void showSlaveLogs(Slave s, Map loggers) throws Exception { + s.getChannel().call(new RemoteLogDumper(s.getNodeName(), loggers)); + } + + private static final class RemoteLogDumper extends MasterToSlaveCallable { + private final String name; + private final Map loggers; + private final TaskListener stderr = StreamTaskListener.fromStderr(); + RemoteLogDumper(String name, Map loggers) { + this.name = name; + this.loggers = loggers; + } + @Override public Void call() throws RuntimeException { + Handler handler = new Handler() { + final Formatter formatter = new SupportLogFormatter(); + @Override public void publish(LogRecord record) { + if (isLoggable(record)) { + stderr.getLogger().print(formatter.format(record).replaceAll("(?m)^", "[" + name + "] ")); + } + } + @Override public void flush() {} + @Override public void close() throws SecurityException {} + }; + handler.setLevel(Level.ALL); + loggers.entrySet().forEach(e -> { + Logger logger = Logger.getLogger(e.getKey()); + logger.setLevel(e.getValue()); + logger.addHandler(handler); + }); + return null; + } + } + /** * Blocks until the ENTER key is hit. * This is useful during debugging a test so that one can inspect the state of Hudson through the web browser. diff --git a/src/main/java/org/jvnet/hudson/test/LoggerRule.java b/src/main/java/org/jvnet/hudson/test/LoggerRule.java index ae05f3aec..1a935b99c 100644 --- a/src/main/java/org/jvnet/hudson/test/LoggerRule.java +++ b/src/main/java/org/jvnet/hudson/test/LoggerRule.java @@ -36,6 +36,7 @@ import java.util.logging.LogRecord; import java.util.logging.Logger; import java.util.logging.SimpleFormatter; +import java.util.stream.Collectors; import javax.annotation.CheckForNull; import javax.annotation.Nonnull; import org.hamcrest.Matcher; @@ -138,6 +139,10 @@ public LoggerRule recordPackage(Class clazz, Level level) { return record(clazz.getPackage().getName(), level); } + Map getRecordedLevels() { + return loggers.keySet().stream().collect(Collectors.toMap(Logger::getName, Logger::getLevel)); + } + /** * Obtains all log records collected so far during this test case. * You must have first called {@link #capture}. From e6b4b0426497d025e54ea51f0ef424167c3af64e Mon Sep 17 00:00:00 2001 From: Jesse Glick Date: Tue, 2 Apr 2019 15:20:01 -0400 Subject: [PATCH 2/2] s/showSlaveLogs/showAgentLogs/g --- src/main/java/org/jvnet/hudson/test/JenkinsRule.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/jvnet/hudson/test/JenkinsRule.java b/src/main/java/org/jvnet/hudson/test/JenkinsRule.java index a5a1433fb..edb01cf15 100644 --- a/src/main/java/org/jvnet/hudson/test/JenkinsRule.java +++ b/src/main/java/org/jvnet/hudson/test/JenkinsRule.java @@ -991,10 +991,10 @@ public void waitOnline(Slave s) throws Exception { } /** - * Same as {@link #showSlaveLogs(Slave, Map)} but taking a preconfigured list of loggers as a convenience. + * Same as {@link #showAgentLogs(Slave, Map)} but taking a preconfigured list of loggers as a convenience. */ - public void showSlaveLogs(Slave s, LoggerRule loggerRule) throws Exception { - showSlaveLogs(s, loggerRule.getRecordedLevels()); + public void showAgentLogs(Slave s, LoggerRule loggerRule) throws Exception { + showAgentLogs(s, loggerRule.getRecordedLevels()); } /** @@ -1004,7 +1004,7 @@ public void showSlaveLogs(Slave s, LoggerRule loggerRule) throws Exception { * @param s an online agent * @param loggers {@link Logger#getName} tied to log level */ - public void showSlaveLogs(Slave s, Map loggers) throws Exception { + public void showAgentLogs(Slave s, Map loggers) throws Exception { s.getChannel().call(new RemoteLogDumper(s.getNodeName(), loggers)); }