Skip to content

Commit

Permalink
Merge pull request #32 from jglick/JEP-210-tests
Browse files Browse the repository at this point in the history
[JENKINS-54133] Encode console notes on master for JEP-210 compatibility
  • Loading branch information
jglick authored Oct 29, 2018
2 parents 350c6da + 0dee874 commit d7dd61e
Show file tree
Hide file tree
Showing 6 changed files with 94 additions and 30 deletions.
7 changes: 7 additions & 0 deletions .mvn/extensions.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<extensions xmlns="http://maven.apache.org/EXTENSIONS/1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/EXTENSIONS/1.0.0 http://maven.apache.org/xsd/core-extensions-1.0.0.xsd">
<extension>
<groupId>io.jenkins.tools.incrementals</groupId>
<artifactId>git-changelist-maven-extension</artifactId>
<version>1.0-beta-7</version>
</extension>
</extensions>
2 changes: 2 additions & 0 deletions .mvn/maven.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
-Pconsume-incrementals
-Pmight-produce-incrementals
25 changes: 17 additions & 8 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@
<parent>
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>plugin</artifactId>
<version>2.31</version>
<version>3.25</version>
<relativePath />
</parent>

<artifactId>ant</artifactId>
<version>1.9-SNAPSHOT</version>
<version>${revision}${changelist}</version>
<packaging>hpi</packaging>
<name>Ant Plugin</name>
<description>Adds Apache Ant support to Jenkins</description>
Expand All @@ -24,18 +24,21 @@
<scm>
<connection>scm:git:git://github.com/jenkinsci/${project.artifactId}-plugin.git</connection>
<developerConnection>scm:git:git@github.com:jenkinsci/${project.artifactId}-plugin.git</developerConnection>
<tag>HEAD</tag>
<tag>${scmTag}</tag>
</scm>

<properties>
<jenkins.version>1.651.3</jenkins.version>
<revision>1.9</revision>
<changelist>-SNAPSHOT</changelist>
<jenkins.version>2.121.2</jenkins.version>
<java.level>8</java.level>
</properties>

<dependencies>
<dependency>
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>structs</artifactId>
<version>1.6</version>
<version>1.17</version>
</dependency>
<dependency>
<groupId>org.jenkins-ci.main</groupId>
Expand All @@ -52,13 +55,13 @@
<dependency>
<groupId>org.jenkins-ci.plugins.workflow</groupId>
<artifactId>workflow-cps</artifactId>
<version>2.32</version>
<version>2.58</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jenkins-ci.plugins.workflow</groupId>
<artifactId>workflow-job</artifactId>
<version>2.9</version>
<version>2.26</version>
<scope>test</scope>
</dependency>
<dependency>
Expand All @@ -70,7 +73,13 @@
<dependency>
<groupId>org.jenkins-ci.plugins.workflow</groupId>
<artifactId>workflow-durable-task-step</artifactId>
<version>2.5</version>
<version>2.26-rc791.37915aaf7f4d</version> <!-- TODO https://github.com/jenkinsci/workflow-durable-task-step-plugin/pull/87 -->
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>durable-task</artifactId>
<version>1.27-rc374.ea1d4ad27dd9</version> <!-- TODO https://github.com/jenkinsci/durable-task-plugin/pull/86 -->
<scope>test</scope>
</dependency>
<dependency>
Expand Down
36 changes: 21 additions & 15 deletions src/main/java/hudson/tasks/Ant.java
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@
import org.kohsuke.stapler.QueryParameter;

import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import hudson.remoting.VirtualChannel;

import java.io.File;
import java.io.IOException;
Expand Down Expand Up @@ -395,22 +396,27 @@ public void buildEnvVars(EnvVars env) {
* Gets the executable path of this Ant on the given target system.
*/
public String getExecutable(Launcher launcher) throws IOException, InterruptedException {
return launcher.getChannel().call(new MasterToSlaveCallable<String,IOException>() {
private static final long serialVersionUID = 906341330603832653L;
public String call() throws IOException {
File exe = getExeFile();
if(exe.exists())
return exe.getPath();
return null;
}
});
VirtualChannel channel = launcher.getChannel();
if (channel == null) {
throw new IOException("offline?");
}
return channel.call(new GetExecutable(getHome()));
}

private File getExeFile() {
String execName = Functions.isWindows() ? "ant.bat" : "ant";
String home = Util.replaceMacro(getHome(), EnvVars.masterEnvVars);

return new File(home,"bin/"+execName);
private static class GetExecutable extends MasterToSlaveCallable<String, IOException> {
private static final long serialVersionUID = 906341330603832653L;
private final String rawHome;
GetExecutable(String rawHome) {
this.rawHome = rawHome;
}
@Override public String call() throws IOException {
String execName = Functions.isWindows() ? "ant.bat" : "ant";
String home = Util.replaceMacro(rawHome, EnvVars.masterEnvVars);
File exe = new File(home, "bin/" + execName);
if (exe.exists()) {
return exe.getPath();
}
return null;
}
}

/**
Expand Down
40 changes: 37 additions & 3 deletions src/main/java/hudson/tasks/_ant/AntConsoleAnnotator.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,14 @@
import hudson.console.ConsoleLogFilter;
import hudson.console.LineTransformationOutputStream;
import hudson.model.Run;
import java.io.ByteArrayOutputStream;

import java.io.IOException;
import java.io.OutputStream;
import java.io.Serializable;
import java.nio.ByteBuffer;
import java.nio.charset.Charset;
import jenkins.util.JenkinsJVM;

/**
* Filter {@link OutputStream} that places an annotation that marks Ant target execution.
Expand All @@ -43,12 +45,32 @@
public class AntConsoleAnnotator extends LineTransformationOutputStream {
private final OutputStream out;
private final Charset charset;
/** Serialized, signed, and Base64-encoded forms of {@link AntTargetNote} and {@link AntOutcomeNote} respectively. */
private final byte[][] antNotes;

private boolean seenEmptyLine;

public AntConsoleAnnotator(OutputStream out, Charset charset) {
this(out, charset, createAntNotes());
}

private AntConsoleAnnotator(OutputStream out, Charset charset, byte[][] antNotes) {
this.out = out;
this.charset = charset;
this.antNotes = antNotes;
}

private static byte[][] createAntNotes() {
JenkinsJVM.checkJenkinsJVM();
try {
ByteArrayOutputStream targetNote = new ByteArrayOutputStream();
new AntTargetNote().encodeTo(targetNote);
ByteArrayOutputStream outcomeNote = new ByteArrayOutputStream();
new AntOutcomeNote().encodeTo(outcomeNote);
return new byte[][] {targetNote.toByteArray(), outcomeNote.toByteArray()};
} catch (IOException x) { // should be impossible
throw new RuntimeException(x);
}
}

@Override
Expand All @@ -60,10 +82,10 @@ protected void eol(byte[] b, int len) throws IOException {

if (seenEmptyLine && endsWith(line,':') && line.indexOf(' ')<0)
// put the annotation
new AntTargetNote().encodeTo(out);
out.write(antNotes[0]);

if (line.equals("BUILD SUCCESSFUL") || line.equals("BUILD FAILED"))
new AntOutcomeNote().encodeTo(out);
out.write(antNotes[1]);

seenEmptyLine = line.length()==0;
out.write(b,0,len);
Expand All @@ -74,6 +96,11 @@ private boolean endsWith(String line, char c) {
return len>0 && line.charAt(len-1)==c;
}

@Override
public void flush() throws IOException {
out.flush();
}

@Override
public void close() throws IOException {
super.close();
Expand All @@ -85,8 +112,15 @@ public static ConsoleLogFilter asConsoleLogFilter() {
}
private static class ConsoleLogFilterImpl extends ConsoleLogFilter implements Serializable {
private static final long serialVersionUID = 1;
private byte[][] antNotes = createAntNotes();
private Object readResolve() {
if (antNotes == null) { // old program.dat
antNotes = createAntNotes();
}
return this;
}
@Override public OutputStream decorateLogger(Run build, OutputStream logger) throws IOException, InterruptedException {
return new AntConsoleAnnotator(logger, Charsets.UTF_8);
return new AntConsoleAnnotator(logger, Charsets.UTF_8, antNotes);
}
}

Expand Down
14 changes: 10 additions & 4 deletions src/test/java/hudson/tasks/AntWrapperTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,10 @@

import com.gargoylesoftware.htmlunit.html.DomElement;
import com.gargoylesoftware.htmlunit.html.HtmlPage;
import hudson.console.ConsoleNote;
import hudson.model.FreeStyleProject;
import hudson.slaves.DumbSlave;
import java.util.logging.Level;
import org.jenkinsci.plugins.workflow.cps.CpsFlowDefinition;
import org.jenkinsci.plugins.workflow.job.WorkflowJob;
import org.jenkinsci.plugins.workflow.job.WorkflowRun;
Expand All @@ -38,6 +41,7 @@
import org.junit.runners.model.Statement;
import org.jvnet.hudson.test.BuildWatcher;
import org.jvnet.hudson.test.JenkinsRule;
import org.jvnet.hudson.test.LoggerRule;
import org.jvnet.hudson.test.RestartableJenkinsRule;
import org.jvnet.hudson.test.ToolInstallations;

Expand All @@ -46,6 +50,7 @@ public class AntWrapperTest {
@ClassRule public static BuildWatcher buildWatcher = new BuildWatcher();
@Rule public RestartableJenkinsRule r = new RestartableJenkinsRule();
@Rule public TemporaryFolder tmp = new TemporaryFolder();
@Rule public LoggerRule logging = new LoggerRule();

@Test public void configRoundTrip() throws Exception {
r.addStep(new Statement() {
Expand All @@ -70,12 +75,13 @@ public class AntWrapperTest {
r.addStep(new Statement() {
@Override public void evaluate() throws Throwable {
ToolInstallations.configureDefaultAnt(tmp); // TODO could instead use DockerRule<JavaContainer> to run against a specified JDK location
DumbSlave s = r.j.createOnlineSlave();
logging.recordPackage(ConsoleNote.class, Level.FINE);
WorkflowJob p = r.j.createProject(WorkflowJob.class, "p");
r.j.jenkins.getWorkspaceFor(p).child("build.xml").copyFrom(AntWrapperTest.class.getResource("_ant/simple-build.xml"));
p.setDefinition(new CpsFlowDefinition("node {withAnt(installation: 'default') {if (isUnix()) {sh 'ant foo'} else {bat 'ant foo'}}}", true));
s.getWorkspaceFor(p).child("build.xml").copyFrom(AntWrapperTest.class.getResource("_ant/simple-build.xml"));
p.setDefinition(new CpsFlowDefinition("node('!master') {withAnt(installation: 'default') {if (isUnix()) {sh 'ant foo'} else {bat 'ant foo'}}}", true));
WorkflowRun b = r.j.buildAndAssertSuccess(p);
// TODO passes locally, fails in jenkins.ci: AntConsoleAnnotator processes AntOutcomeNote but not AntTargetNote
// (perhaps because it seems to have set ANT_HOME=/opt/ant/latest? yet the output looks right)
b.getLogText().writeRawLogTo(0, System.err);
AntTest.assertHtmlLogContains(b, "<b class=ant-target>foo</b>");
AntTest.assertHtmlLogContains(b, "<b class=ant-target>bar</b>");
JenkinsRule.WebClient wc = r.j.createWebClient();
Expand Down

0 comments on commit d7dd61e

Please sign in to comment.