Skip to content

Commit

Permalink
[JENKINS-27392] SimpleBuildWrapper.createLoggerDecorator
Browse files Browse the repository at this point in the history
  • Loading branch information
jglick committed Mar 31, 2015
1 parent 11ac075 commit a52d665
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 5 deletions.
18 changes: 13 additions & 5 deletions core/src/main/java/jenkins/tasks/SimpleBuildWrapper.java
Expand Up @@ -28,6 +28,7 @@
import hudson.EnvVars;
import hudson.FilePath;
import hudson.Launcher;
import hudson.console.ConsoleLogFilter;
import hudson.model.AbstractBuild;
import hudson.model.AbstractProject;
import hudson.model.Action;
Expand Down Expand Up @@ -177,12 +178,19 @@ private class EnvironmentWrapper extends Environment {
}
}

/**
* Allows this wrapper to decorate log output.
* @param build as is passed to {@link #setUp(Context, Run, FilePath, Launcher, TaskListener, EnvVars)}
* @return a filter which ignores its {@code build} parameter and is {@link Serializable}; or null (the default)
* @since 1.608
*/
public @CheckForNull ConsoleLogFilter createLoggerDecorator(@Nonnull Run<?,?> build) {
return null;
}

@Override public final OutputStream decorateLogger(AbstractBuild build, OutputStream logger) throws IOException, InterruptedException, Run.RunnerAbortedException {
// Doubtful this can be supported.
// Decorating a TaskListener would be more reasonable.
// But for an AbstractBuild this is called early in Run.execute, before setUp.
// And for other kinds of builds, it is unclear what this would even mean.
return logger;
ConsoleLogFilter filter = createLoggerDecorator(build);
return filter != null ? filter.decorateLogger(build, logger) : logger;
}

@Override public final Launcher decorateLauncher(AbstractBuild build, Launcher launcher, BuildListener listener) throws IOException, InterruptedException, Run.RunnerAbortedException {
Expand Down
49 changes: 49 additions & 0 deletions test/src/test/java/jenkins/tasks/SimpleBuildWrapperTest.java
Expand Up @@ -28,7 +28,11 @@
import hudson.FilePath;
import hudson.Functions;
import hudson.Launcher;
import hudson.console.ConsoleLogFilter;
import hudson.console.LineTransformationOutputStream;
import hudson.model.AbstractBuild;
import hudson.model.AbstractProject;
import hudson.model.BuildListener;
import hudson.model.Computer;
import hudson.model.Descriptor;
import hudson.model.FreeStyleBuild;
Expand All @@ -45,18 +49,26 @@
import hudson.tasks.Shell;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.io.Serializable;
import java.util.Collections;
import java.util.Locale;
import org.junit.Test;
import static org.junit.Assert.*;
import org.junit.Assume;
import org.junit.ClassRule;
import org.junit.Rule;
import org.junit.rules.TemporaryFolder;
import org.jvnet.hudson.test.BuildWatcher;
import org.jvnet.hudson.test.CaptureEnvironmentBuilder;
import org.jvnet.hudson.test.Issue;
import org.jvnet.hudson.test.JenkinsRule;
import org.jvnet.hudson.test.TestBuilder;
import org.jvnet.hudson.test.TestExtension;

public class SimpleBuildWrapperTest {

@ClassRule public static BuildWatcher buildWatcher = new BuildWatcher();
@Rule public JenkinsRule r = new JenkinsRule();
@Rule public TemporaryFolder tmp = new TemporaryFolder();

Expand Down Expand Up @@ -162,7 +174,44 @@ private static final class DisposerImpl extends Disposer {
return true;
}
}
}

@Issue("JENKINS-27392")
@Test public void loggerDecorator() throws Exception {
FreeStyleProject p = r.createFreeStyleProject();
p.getBuildWrappersList().add(new WrapperWithLogger());
p.getBuildersList().add(new TestBuilder() {
@Override public boolean perform(AbstractBuild<?,?> build, Launcher launcher, BuildListener listener) throws InterruptedException, IOException {
listener.getLogger().println("sending a message");
return true;
}
});
r.assertLogContains("SENDING A MESSAGE", r.buildAndAssertSuccess(p));
}
public static class WrapperWithLogger extends SimpleBuildWrapper {
@Override public void setUp(Context context, Run<?,?> build, FilePath workspace, Launcher launcher, TaskListener listener, EnvVars initialEnvironment) throws IOException, InterruptedException {}
@Override public ConsoleLogFilter createLoggerDecorator(Run<?,?> build) {
return new UpcaseFilter();
}
private static class UpcaseFilter extends ConsoleLogFilter implements Serializable {
private static final long serialVersionUID = 1;
@SuppressWarnings("rawtypes") // inherited
@Override public OutputStream decorateLogger(AbstractBuild _ignore, final OutputStream logger) throws IOException, InterruptedException {
return new LineTransformationOutputStream() {
@Override protected void eol(byte[] b, int len) throws IOException {
logger.write(new String(b, 0, len).toUpperCase(Locale.ROOT).getBytes());
}
};
}
}
@TestExtension("loggerDecorator") public static class DescriptorImpl extends BuildWrapperDescriptor {
@Override public String getDisplayName() {
return "WrapperWithLogger";
}
@Override public boolean isApplicable(AbstractProject<?,?> item) {
return true;
}
}
}

}

0 comments on commit a52d665

Please sign in to comment.