Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Final line of shell output without newline lost when using LineTransformationOutputStream-based decorators #112

Merged
merged 6 commits into from
Jul 25, 2019
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@
<revision>2.33</revision>
<changelist>-SNAPSHOT</changelist>
<jenkins.version>2.176.1</jenkins.version>
<jenkins-test-harness.version>2.54-rc1207.a9cdd7c1192a</jenkins-test-harness.version> <!-- TODO https://github.com/jenkinsci/jenkins-test-harness/pull/149 -->
jglick marked this conversation as resolved.
Show resolved Hide resolved
<java.level>8</java.level>
<useBeta>true</useBeta>
<workflow-step-api-plugin.version>2.20</workflow-step-api-plugin.version>
Expand All @@ -79,7 +80,7 @@
<dependency>
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>durable-task</artifactId>
<version>1.29</version>
<version>1.31-rc427.7bfff1482201</version> <!-- TODO https://github.com/jenkinsci/durable-task-plugin/pull/102 -->
jglick marked this conversation as resolved.
Show resolved Hide resolved
</dependency>
<dependency>
<groupId>org.jenkins-ci.plugins.workflow</groupId>
Expand Down Expand Up @@ -132,7 +133,7 @@
<dependency>
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>credentials-binding</artifactId>
<version>1.16</version>
<version>1.17</version>
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To pick up jenkinsci/credentials-binding-plugin#51. This seems to be the reason that, in watch mode, the test was previously failing (output was getting lost) even in situations that did not involve a missing final newline.

<scope>test</scope>
</dependency>
<dependency>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -584,6 +584,7 @@ private interface OutputSupplier {
byte[] produce() throws IOException, InterruptedException;
}
private void handleExit(int exitCode, OutputSupplier output) throws IOException, InterruptedException {
listener().getLogger().println(); // TODO
Throwable originalCause = causeOfStoppage;
if ((returnStatus && originalCause == null) || exitCode == 0) {
getContext().onSuccess(returnStatus ? exitCode : returnStdout ? new String(output.produce(), StandardCharsets.UTF_8) : null);
Expand Down Expand Up @@ -658,6 +659,7 @@ private static class HandlerImpl extends Handler {
synchronized (ps) { // like PrintStream.write overloads do
IOUtils.copy(stream, os);
}
ps.println(); // TODO
} else {
// A subclass. Who knows why, but trust any write(…) overrides it may have.
IOUtils.copy(stream, ps);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,13 @@
import hudson.console.ConsoleNote;
import hudson.console.LineTransformationOutputStream;
import hudson.model.BallColor;
import hudson.model.BooleanParameterDefinition;
import hudson.model.BooleanParameterValue;
import hudson.model.BuildListener;
import hudson.model.FreeStyleProject;
import hudson.model.Node;
import hudson.model.ParametersAction;
import hudson.model.ParametersDefinitionProperty;
import hudson.model.Result;
import hudson.model.Run;
import hudson.remoting.Channel;
Expand All @@ -44,7 +48,6 @@
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.Callable;
import java.util.logging.Level;
import java.util.logging.LogRecord;
import javax.annotation.CheckForNull;
Expand Down Expand Up @@ -85,7 +88,6 @@
import org.junit.Assume;
import static org.junit.Assume.assumeFalse;
import org.junit.ClassRule;
import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ErrorCollector;
Expand Down Expand Up @@ -601,39 +603,39 @@ private static final class HelloNote extends ConsoleNote<Object> {
j.assertLogContains("¡Čau → there!", j.buildAndAssertSuccess(p));
}

@Ignore("TODO missing final line and in some cases even the `+ set +x` (but passes without withCredentials)")
@Test public void missingNewline() throws Exception {
assumeFalse(Functions.isWindows()); // TODO create Windows equivalent
String credentialsId = "creds";
String username = "bob";
String password = "s3cr3t";
UsernamePasswordCredentialsImpl c = new UsernamePasswordCredentialsImpl(CredentialsScope.GLOBAL, credentialsId, "sample", username, password);
CredentialsProvider.lookupStores(j.jenkins).iterator().next().addCredentials(Domain.global(), c);
j.createSlave("remote", null, null);
DumbSlave s = j.createSlave("remote", null, null);
j.waitOnline(s);
logging.record(DurableTaskStep.class, Level.FINE).record(FileMonitoringTask.class, Level.FINE);
j.showAgentLogs(s, logging);
WorkflowJob p = j.jenkins.createProject(WorkflowJob.class, "p");
p.addProperty(new ParametersDefinitionProperty(new BooleanParameterDefinition("WATCHING", false, null)));
p.setDefinition(new CpsFlowDefinition(
"node('master') {\n" +
" withCredentials([usernameColonPassword(variable: 'USERPASS', credentialsId: '" + credentialsId + "')]) {\n" +
" sh 'set +x; printf \"some local output\"'\n" +
" }\n" +
"}\n" +
"node('remote') {\n" +
" withCredentials([usernameColonPassword(variable: 'USERPASS', credentialsId: '" + credentialsId + "')]) {\n" +
" sh 'set +x; printf \"some remote output\"'\n" +
"['master', 'remote'].each {label ->\n" +
" node(label) {\n" +
" withCredentials([usernameColonPassword(variable: 'USERPASS', credentialsId: '" + credentialsId + "')]) {\n" +
" sh 'set +x; echo \"with final newline node=$NODE_NAME watching=$WATCHING\"'\n" +
" sh 'set +x; printf \"missing final newline node=$NODE_NAME watching=$WATCHING\"'\n" +
" }\n" +
" }\n" +
"}", true));
Callable<Void> test = () -> {
WorkflowRun b = j.assertBuildStatusSuccess(p.scheduleBuild2(0));
j.assertLogContains("some local output", b);
j.assertLogContains("some remote output", b);
return null;
};
boolean origUseWatching = DurableTaskStep.USE_WATCHING;
try {
DurableTaskStep.USE_WATCHING = false;
errors.checkSucceeds(test);
DurableTaskStep.USE_WATCHING = true;
errors.checkSucceeds(test);
for (boolean watching : new boolean[] {false, true}) {
DurableTaskStep.USE_WATCHING = watching;
String log = JenkinsRule.getLog(j.assertBuildStatusSuccess(p.scheduleBuild2(0, new ParametersAction(new BooleanParameterValue("WATCHING", watching)))));
for (String node : new String[] {"master", "remote"}) {
for (String mode : new String[] {"with", "missing"}) {
errors.checkThat(log, containsString(mode + " final newline node=" + node + " watching=" + watching));
}
}
}
} finally {
DurableTaskStep.USE_WATCHING = origUseWatching;
}
Expand Down