diff --git a/src/main/java/org/jenkinsci/plugins/workflow/steps/durable_task/DurableTaskStep.java b/src/main/java/org/jenkinsci/plugins/workflow/steps/durable_task/DurableTaskStep.java index 2eca1ce1..03b8df32 100644 --- a/src/main/java/org/jenkinsci/plugins/workflow/steps/durable_task/DurableTaskStep.java +++ b/src/main/java/org/jenkinsci/plugins/workflow/steps/durable_task/DurableTaskStep.java @@ -31,6 +31,7 @@ import hudson.FilePath; import hudson.Functions; import hudson.Launcher; +import hudson.Main; import hudson.Util; import hudson.model.Node; import hudson.model.TaskListener; @@ -170,7 +171,7 @@ interface ExecutionRemotable { /** If set to false, disables {@link Execution#watching} mode. */ @SuppressFBWarnings(value = "MS_SHOULD_BE_FINAL", justification = "public & mutable only for tests") @Restricted(NoExternalUse.class) - public static boolean USE_WATCHING = !"false".equals(System.getProperty(DurableTaskStep.class.getName() + ".USE_WATCHING")); + public static boolean USE_WATCHING = Boolean.parseBoolean(System.getProperty(DurableTaskStep.class.getName() + ".USE_WATCHING", Main.isUnitTest ? "true" : /* JENKINS-52165 turn back on by default */ "false")); /** * Represents one task that is believed to still be running. @@ -466,14 +467,7 @@ private void check() { if (controller.writeLog(workspace, listener.getLogger())) { LOGGER.log(Level.FINE, "last-minute output in {0} on {1}", new Object[] {remote, node}); } - if (returnStatus || exitCode == 0) { - getContext().onSuccess(returnStatus ? exitCode : returnStdout ? new String(controller.getOutput(workspace, launcher()), StandardCharsets.UTF_8) : null); - } else { - if (returnStdout) { - listener.getLogger().write(controller.getOutput(workspace, launcher())); // diagnostic - } - getContext().onFailure(new AbortException("script returned exit code " + exitCode)); - } + handleExit(exitCode, () -> controller.getOutput(workspace, launcher())); recurrencePeriod = 0; controller.cleanup(workspace); } @@ -507,12 +501,20 @@ private void check() { return; } recurrencePeriod = 0; + handleExit(exitCode, () -> output); + } + + @FunctionalInterface + private interface OutputSupplier { + byte[] produce() throws IOException, InterruptedException; + } + private void handleExit(int exitCode, OutputSupplier output) throws IOException, InterruptedException { Throwable originalCause = causeOfStoppage; if ((returnStatus && originalCause == null) || exitCode == 0) { - getContext().onSuccess(returnStatus ? exitCode : returnStdout ? new String(output, StandardCharsets.UTF_8) : null); + getContext().onSuccess(returnStatus ? exitCode : returnStdout ? new String(output.produce(), StandardCharsets.UTF_8) : null); } else { if (returnStdout) { - listener().getLogger().write(output); // diagnostic + listener().getLogger().write(output.produce()); // diagnostic } if (originalCause != null) { // JENKINS-28822: Use the previous cause instead of throwing a new AbortException diff --git a/src/test/java/org/jenkinsci/plugins/workflow/steps/durable_task/ShellStepTest.java b/src/test/java/org/jenkinsci/plugins/workflow/steps/durable_task/ShellStepTest.java index 7672da08..586be277 100644 --- a/src/test/java/org/jenkinsci/plugins/workflow/steps/durable_task/ShellStepTest.java +++ b/src/test/java/org/jenkinsci/plugins/workflow/steps/durable_task/ShellStepTest.java @@ -541,7 +541,7 @@ private Object writeReplace() { j.waitForCompletion(b); // Would have succeeded before https://github.com/jenkinsci/workflow-durable-task-step-plugin/pull/75. j.assertBuildStatus(Result.ABORTED, b); - j.assertLogContains("Timeout has been exceeded", b); + j.waitForMessage("Timeout has been exceeded", b); // TODO assertLogContains fails unless a sleep is introduced; possible race condition in waitForCompletion } /**