Index: subprojects/internal-integ-testing/src/main/groovy/org/gradle/integtests/fixtures/executer/DefaultGradleDistribution.java =================================================================== diff -u -N -r3a84511f4e22fef13680330b7b1245bd682c7543 -r410a52b5b4cf97750f0e1b8fee12f8b63f5665d1 --- subprojects/internal-integ-testing/src/main/groovy/org/gradle/integtests/fixtures/executer/DefaultGradleDistribution.java (.../DefaultGradleDistribution.java) (revision 3a84511f4e22fef13680330b7b1245bd682c7543) +++ subprojects/internal-integ-testing/src/main/groovy/org/gradle/integtests/fixtures/executer/DefaultGradleDistribution.java (.../DefaultGradleDistribution.java) (revision 410a52b5b4cf97750f0e1b8fee12f8b63f5665d1) @@ -215,14 +215,23 @@ } @Override + public boolean isToolingApiHasCauseOnPhasedActionFail() { + return isSameOrNewer("5.1"); + } + + @Override + public boolean isToolingApiMergesStderrIntoStdout() { + return isSameOrNewer("4.7") && isSameOrOlder("5.0"); + } + + @Override public boolean isToolingApiLogsConfigureSummary() { return isSameOrNewer("2.14"); } @Override public T selectOutputWithFailureLogging(T stdout, T stderr) { - if (isSameOrNewer("4.0") && isSameOrOlder("4.6")) { - // This only worked as expected for a while + if (isSameOrNewer("4.0") && isSameOrOlder("4.6") || isSameOrNewer("5.1")) { return stderr; } return stdout; Index: subprojects/internal-integ-testing/src/main/groovy/org/gradle/integtests/fixtures/executer/GradleDistribution.java =================================================================== diff -u -N -r3a84511f4e22fef13680330b7b1245bd682c7543 -r410a52b5b4cf97750f0e1b8fee12f8b63f5665d1 --- subprojects/internal-integ-testing/src/main/groovy/org/gradle/integtests/fixtures/executer/GradleDistribution.java (.../GradleDistribution.java) (revision 3a84511f4e22fef13680330b7b1245bd682c7543) +++ subprojects/internal-integ-testing/src/main/groovy/org/gradle/integtests/fixtures/executer/GradleDistribution.java (.../GradleDistribution.java) (revision 410a52b5b4cf97750f0e1b8fee12f8b63f5665d1) @@ -132,6 +132,16 @@ boolean isToolingApiLogsFailureOnCancel(); /** + * Returns true if this version retains the original exception as cause on phased action fail. + */ + boolean isToolingApiHasCauseOnPhasedActionFail(); + + /** + * Returns true if this version logs errors to stdout instead of stderr. + */ + boolean isToolingApiMergesStderrIntoStdout(); + + /** * Returns the logging output stream that this version logs build failures to when invoked via the tooling API. */ T selectOutputWithFailureLogging(T stdout, T stderr); Index: subprojects/logging/src/main/java/org/gradle/internal/logging/LoggingOutputInternal.java =================================================================== diff -u -N -rf4e19954ed63dbe9bbb3386fe8b636776a654726 -r410a52b5b4cf97750f0e1b8fee12f8b63f5665d1 --- subprojects/logging/src/main/java/org/gradle/internal/logging/LoggingOutputInternal.java (.../LoggingOutputInternal.java) (revision f4e19954ed63dbe9bbb3386fe8b636776a654726) +++ subprojects/logging/src/main/java/org/gradle/internal/logging/LoggingOutputInternal.java (.../LoggingOutputInternal.java) (revision 410a52b5b4cf97750f0e1b8fee12f8b63f5665d1) @@ -22,6 +22,7 @@ import org.gradle.internal.nativeintegration.console.ConsoleMetaData; import org.gradle.internal.scan.UsedByScanPlugin; +import javax.annotation.Nullable; import java.io.OutputStream; /** @@ -64,7 +65,7 @@ * @param consoleMetadata The metadata associated with this console * @param consoleOutput The output format. */ - void attachConsole(OutputStream outputStream, OutputStream errorStream, ConsoleOutput consoleOutput, ConsoleMetaData consoleMetadata); + void attachConsole(OutputStream outputStream, OutputStream errorStream, ConsoleOutput consoleOutput, @Nullable ConsoleMetaData consoleMetadata); /** * Adds the given {@link java.io.OutputStream} as a logging destination. The stream receives stdout logging formatted according to the current logging settings and Index: subprojects/logging/src/main/java/org/gradle/internal/logging/services/DefaultLoggingManager.java =================================================================== diff -u -N -rf4e19954ed63dbe9bbb3386fe8b636776a654726 -r410a52b5b4cf97750f0e1b8fee12f8b63f5665d1 --- subprojects/logging/src/main/java/org/gradle/internal/logging/services/DefaultLoggingManager.java (.../DefaultLoggingManager.java) (revision f4e19954ed63dbe9bbb3386fe8b636776a654726) +++ subprojects/logging/src/main/java/org/gradle/internal/logging/services/DefaultLoggingManager.java (.../DefaultLoggingManager.java) (revision 410a52b5b4cf97750f0e1b8fee12f8b63f5665d1) @@ -29,7 +29,6 @@ import org.gradle.internal.logging.events.OutputEventListener; import org.gradle.internal.logging.text.StreamBackedStandardOutputListener; import org.gradle.internal.nativeintegration.console.ConsoleMetaData; -import org.gradle.internal.nativeintegration.console.FallbackConsoleMetaData; import java.io.Closeable; import java.io.OutputStream; @@ -219,7 +218,7 @@ @Override public void attachConsole(OutputStream outputStream, OutputStream errorStream, ConsoleOutput consoleOutput) { - loggingRouter.attachConsole(outputStream, errorStream, consoleOutput, FallbackConsoleMetaData.INSTANCE); + loggingRouter.attachConsole(outputStream, errorStream, consoleOutput, null); } @Override Index: subprojects/logging/src/main/java/org/gradle/internal/logging/sink/ConsoleConfigureAction.java =================================================================== diff -u -N -rf9b5e7f8a51be4fb585fa4ada0d83c6b7037583f -r410a52b5b4cf97750f0e1b8fee12f8b63f5665d1 --- subprojects/logging/src/main/java/org/gradle/internal/logging/sink/ConsoleConfigureAction.java (.../ConsoleConfigureAction.java) (revision f9b5e7f8a51be4fb585fa4ada0d83c6b7037583f) +++ subprojects/logging/src/main/java/org/gradle/internal/logging/sink/ConsoleConfigureAction.java (.../ConsoleConfigureAction.java) (revision 410a52b5b4cf97750f0e1b8fee12f8b63f5665d1) @@ -25,6 +25,7 @@ import org.gradle.internal.nativeintegration.console.TestConsoleMetadata; import org.gradle.internal.nativeintegration.services.NativeServices; +import javax.annotation.Nullable; import java.io.OutputStream; import java.io.OutputStreamWriter; @@ -78,21 +79,23 @@ renderer.addPlainConsole(consoleMetaData != null && consoleMetaData.isStdOut() && consoleMetaData.isStdErr()); } - private static void configureRichConsole(OutputEventRenderer renderer, ConsoleMetaData consoleMetaData, boolean force, boolean verbose) { - consoleMetaData = consoleMetaData == null ? FallbackConsoleMetaData.INSTANCE : consoleMetaData; + private static void configureRichConsole(OutputEventRenderer renderer, @Nullable ConsoleMetaData consoleMetaData, boolean force, boolean verbose) { + if (consoleMetaData == null) { + consoleMetaData = FallbackConsoleMetaData.ATTACHED; + } if (consoleMetaData.isStdOut()) { OutputStream originalStdOut = renderer.getOriginalStdOut(); OutputStreamWriter outStr = new OutputStreamWriter(force ? originalStdOut : AnsiConsoleUtil.wrapOutputStream(originalStdOut)); Console console = new AnsiConsole(outStr, outStr, renderer.getColourMap(), consoleMetaData, force); - renderer.addRichConsole(console, true, consoleMetaData.isStdErr(), consoleMetaData, verbose); + renderer.addRichConsole(console, consoleMetaData, verbose); } else if (consoleMetaData.isStdErr()) { // Only stderr is connected to a terminal OutputStream originalStdErr = renderer.getOriginalStdErr(); OutputStreamWriter errStr = new OutputStreamWriter(force ? originalStdErr : AnsiConsoleUtil.wrapOutputStream(originalStdErr)); Console console = new AnsiConsole(errStr, errStr, renderer.getColourMap(), consoleMetaData, force); - renderer.addRichConsole(console, false, true, consoleMetaData, verbose); + renderer.addRichConsole(console, consoleMetaData, verbose); } else { - renderer.addRichConsole(null, false, false, consoleMetaData, verbose); + renderer.addRichConsole(null, consoleMetaData, verbose); } } } Index: subprojects/logging/src/main/java/org/gradle/internal/logging/sink/OutputEventRenderer.java =================================================================== diff -u -N -rd3cb260dee5ebed45332423c9781c4c17f4d3dfc -r410a52b5b4cf97750f0e1b8fee12f8b63f5665d1 --- subprojects/logging/src/main/java/org/gradle/internal/logging/sink/OutputEventRenderer.java (.../OutputEventRenderer.java) (revision d3cb260dee5ebed45332423c9781c4c17f4d3dfc) +++ subprojects/logging/src/main/java/org/gradle/internal/logging/sink/OutputEventRenderer.java (.../OutputEventRenderer.java) (revision 410a52b5b4cf97750f0e1b8fee12f8b63f5665d1) @@ -52,6 +52,7 @@ import org.gradle.internal.nativeintegration.console.FallbackConsoleMetaData; import org.gradle.internal.time.Clock; +import javax.annotation.Nullable; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.util.concurrent.atomic.AtomicReference; @@ -150,31 +151,31 @@ @Override public void attachConsole(OutputStream outputStream, OutputStream errorStream, ConsoleOutput consoleOutput) { - attachConsole(outputStream, errorStream, consoleOutput, FallbackConsoleMetaData.INSTANCE); + attachConsole(outputStream, errorStream, consoleOutput, null); } @Override - public void attachConsole(OutputStream outputStream, OutputStream errorStream, ConsoleOutput consoleOutput, ConsoleMetaData consoleMetadata) { + public void attachConsole(OutputStream outputStream, OutputStream errorStream, ConsoleOutput consoleOutput, @Nullable ConsoleMetaData consoleMetadata) { synchronized (lock) { + if (consoleMetadata == null) { + consoleMetadata = consoleOutput == ConsoleOutput.Plain ? FallbackConsoleMetaData.NOT_ATTACHED : FallbackConsoleMetaData.ATTACHED; + } StandardOutputListener outputListener = new StreamBackedStandardOutputListener(outputStream); StandardOutputListener errorListener = new StreamBackedStandardOutputListener(errorStream); if (consoleOutput == ConsoleOutput.Plain) { - addPlainConsole(outputListener, errorListener, consoleMetadata != null && (consoleMetadata.isStdErr() && consoleMetadata.isStdOut())); + addPlainConsole(outputListener, errorListener, consoleMetadata.isStdOut() && consoleMetadata.isStdErr()); } else { - if (consoleMetadata == null) { - consoleMetadata = FallbackConsoleMetaData.INSTANCE; - } Console console; if (consoleMetadata.isStdOut()) { OutputStreamWriter writer = new OutputStreamWriter(outputStream); - console =new AnsiConsole(writer, writer, getColourMap(), consoleMetadata, true); + console = new AnsiConsole(writer, writer, getColourMap(), consoleMetadata, true); } else if (consoleMetadata.isStdErr()) { OutputStreamWriter writer = new OutputStreamWriter(errorStream); - console =new AnsiConsole(writer, writer, getColourMap(), consoleMetadata, true); + console = new AnsiConsole(writer, writer, getColourMap(), consoleMetadata, true); } else { console = null; } - addRichConsole(console, consoleMetadata.isStdOut(), consoleMetadata.isStdErr(), outputListener, errorListener, consoleMetadata, consoleOutput == ConsoleOutput.Verbose); + addRichConsole(console, outputListener, errorListener, consoleMetadata, consoleOutput == ConsoleOutput.Verbose); } } } @@ -246,16 +247,18 @@ } } - public OutputEventRenderer addRichConsole(Console console, boolean stdoutAttachedToConsole, boolean stderrAttachedToConsole, ConsoleMetaData consoleMetaData) { - return addRichConsole(console, stdoutAttachedToConsole, stderrAttachedToConsole, consoleMetaData, false); + public OutputEventRenderer addRichConsole(Console console, ConsoleMetaData consoleMetaData) { + return addRichConsole(console, consoleMetaData, false); } - public OutputEventRenderer addRichConsole(Console console, boolean stdoutAttachedToConsole, boolean stderrAttachedToConsole, ConsoleMetaData consoleMetaData, boolean verbose) { - return addRichConsole(console, stdoutAttachedToConsole, stderrAttachedToConsole, new StreamBackedStandardOutputListener((Appendable) originalStdOut), new StreamBackedStandardOutputListener((Appendable)originalStdErr), consoleMetaData, verbose); + public OutputEventRenderer addRichConsole(Console console, ConsoleMetaData consoleMetaData, boolean verbose) { + return addRichConsole(console, new StreamBackedStandardOutputListener((Appendable) originalStdOut), new StreamBackedStandardOutputListener((Appendable) originalStdErr), consoleMetaData, verbose); } - private OutputEventRenderer addRichConsole(Console console, boolean stdoutAttachedToConsole, boolean stderrAttachedToConsole, StandardOutputListener outputListener, StandardOutputListener errorListener, ConsoleMetaData consoleMetaData, boolean verbose) { + private OutputEventRenderer addRichConsole(Console console, StandardOutputListener outputListener, StandardOutputListener errorListener, ConsoleMetaData consoleMetaData, boolean verbose) { OutputEventListener consoleChain; + boolean stdoutAttachedToConsole = consoleMetaData.isStdOut(); + boolean stderrAttachedToConsole = consoleMetaData.isStdErr(); if (stdoutAttachedToConsole && stderrAttachedToConsole) { OutputEventListener consoleListener = new StyledTextOutputBackedRenderer(console.getBuildOutputArea()); consoleChain = getRichConsoleChain(console, consoleMetaData, verbose, consoleListener); @@ -300,7 +303,7 @@ } private OutputEventListener getPlainConsoleChain(boolean redirectStderr) { - return getPlainConsoleChain(new StreamBackedStandardOutputListener((Appendable) originalStdOut), new StreamBackedStandardOutputListener((Appendable)originalStdErr), redirectStderr, true); + return getPlainConsoleChain(new StreamBackedStandardOutputListener((Appendable) originalStdOut), new StreamBackedStandardOutputListener((Appendable) originalStdErr), redirectStderr, true); } private OutputEventListener getPlainConsoleChain(StandardOutputListener outputListener, StandardOutputListener errorListener, boolean redirectStderr, boolean verbose) { Index: subprojects/logging/src/test/groovy/org/gradle/internal/logging/services/DefaultLoggingManagerTest.groovy =================================================================== diff -u -N -rf4e19954ed63dbe9bbb3386fe8b636776a654726 -r410a52b5b4cf97750f0e1b8fee12f8b63f5665d1 --- subprojects/logging/src/test/groovy/org/gradle/internal/logging/services/DefaultLoggingManagerTest.groovy (.../DefaultLoggingManagerTest.groovy) (revision f4e19954ed63dbe9bbb3386fe8b636776a654726) +++ subprojects/logging/src/test/groovy/org/gradle/internal/logging/services/DefaultLoggingManagerTest.groovy (.../DefaultLoggingManagerTest.groovy) (revision 410a52b5b4cf97750f0e1b8fee12f8b63f5665d1) @@ -22,12 +22,11 @@ import org.gradle.internal.logging.config.LoggingSourceSystem import org.gradle.internal.logging.config.LoggingSystem import org.gradle.internal.logging.events.OutputEventListener -import org.gradle.internal.nativeintegration.console.FallbackConsoleMetaData import org.gradle.util.RedirectStdOutAndErr import org.junit.Rule import spock.lang.Specification -public class DefaultLoggingManagerTest extends Specification { +class DefaultLoggingManagerTest extends Specification { @Rule public final RedirectStdOutAndErr outputs = new RedirectStdOutAndErr(); private final def slf4jLoggingSystem = Mock(LoggingSourceSystem) @@ -490,7 +489,7 @@ then: 1 * loggingRouter.snapshot() >> snapshot - 1 * loggingRouter.attachConsole(output, error, ConsoleOutput.Verbose, FallbackConsoleMetaData.INSTANCE) + 1 * loggingRouter.attachConsole(output, error, ConsoleOutput.Verbose, null) 0 * loggingRouter._ when: @@ -517,7 +516,7 @@ loggingManager.attachConsole(output, error, ConsoleOutput.Verbose) then: - 1 * loggingRouter.attachConsole(output, error, ConsoleOutput.Verbose, FallbackConsoleMetaData.INSTANCE) + 1 * loggingRouter.attachConsole(output, error, ConsoleOutput.Verbose, null) 0 * loggingRouter._ when: Index: subprojects/logging/src/test/groovy/org/gradle/internal/logging/sink/OutputEventRendererTest.groovy =================================================================== diff -u -N -r71342de47d31fa449337cc89d1c4667144b53aca -r410a52b5b4cf97750f0e1b8fee12f8b63f5665d1 --- subprojects/logging/src/test/groovy/org/gradle/internal/logging/sink/OutputEventRendererTest.groovy (.../OutputEventRendererTest.groovy) (revision 71342de47d31fa449337cc89d1c4667144b53aca) +++ subprojects/logging/src/test/groovy/org/gradle/internal/logging/sink/OutputEventRendererTest.groovy (.../OutputEventRendererTest.groovy) (revision 410a52b5b4cf97750f0e1b8fee12f8b63f5665d1) @@ -286,7 +286,9 @@ def rendersLogEventsWhenStdOutAndStdErrAreConsole() { def snapshot = renderer.snapshot() - renderer.addRichConsole(console, true, true, metaData) + metaData.stdOut >> true + metaData.stdErr >> true + renderer.addRichConsole(console, metaData) when: renderer.onOutput(start(description: 'description', buildOperationStart: true, id: 1L, buildOperationId: 1L, buildOperationCategory: BuildOperationCategory.TASK)) @@ -301,8 +303,10 @@ def rendersLogEventsWhenOnlyStdOutIsConsole() { def snapshot = renderer.snapshot() + metaData.stdOut >> true + metaData.stdErr >> false renderer.attachSystemOutAndErr() - renderer.addRichConsole(console, true, false, metaData) + renderer.addRichConsole(console, metaData) when: renderer.onOutput(start(description: 'description', buildOperationStart: true, id: 1L, buildOperationId: 1L, buildOperationCategory: BuildOperationCategory.TASK)) @@ -317,8 +321,10 @@ def rendersLogEventsWhenOnlyStdErrIsConsole() { def snapshot = renderer.snapshot() + metaData.stdOut >> false + metaData.stdErr >> true renderer.attachSystemOutAndErr() - renderer.addRichConsole(console, false, true, metaData) + renderer.addRichConsole(console, metaData) when: renderer.onOutput(start('description')) @@ -334,7 +340,9 @@ def rendersLogEventsInConsoleWhenLogLevelIsDebug() { renderer.configure(LogLevel.DEBUG) def snapshot = renderer.snapshot() - renderer.addRichConsole(console, true, true, metaData) + metaData.stdOut >> true + metaData.stdErr >> true + renderer.addRichConsole(console, metaData) when: renderer.onOutput(event(tenAm, 'info', LogLevel.INFO)) @@ -349,7 +357,9 @@ when: renderer.attachSystemOutAndErr() def snapshot = renderer.snapshot() - renderer.addRichConsole(console, true, true, metaData) + metaData.stdOut >> true + metaData.stdErr >> true + renderer.addRichConsole(console, metaData) renderer.onOutput(event('info', LogLevel.INFO)) renderer.onOutput(event('error', LogLevel.ERROR)) renderer.restore(snapshot) // close console to flush @@ -364,7 +374,9 @@ when: renderer.attachSystemOutAndErr() def snapshot = renderer.snapshot() - renderer.addRichConsole(console, true, false, metaData) + metaData.stdOut >> true + metaData.stdErr >> false + renderer.addRichConsole(console, metaData) renderer.onOutput(event('info', LogLevel.INFO)) renderer.onOutput(event('error', LogLevel.ERROR)) renderer.restore(snapshot) // close console to flush @@ -379,7 +391,9 @@ when: renderer.attachSystemOutAndErr() def snapshot = renderer.snapshot() - renderer.addRichConsole(console, false, true, metaData) + metaData.stdOut >> false + metaData.stdErr >> true + renderer.addRichConsole(console, metaData) renderer.onOutput(event('info', LogLevel.INFO)) renderer.onOutput(event('error', LogLevel.ERROR)) renderer.restore(snapshot) // close console to flush @@ -405,8 +419,8 @@ renderer.restore(snapshot) // close console to flush then: - output.toString().readLines() == ['un-grouped error', '', '> description status', 'info', 'error'] - error.toString().empty + output.toString().readLines() == ['', '> description status', 'info'] + error.toString().readLines() == ['un-grouped error', 'error'] } def "renders log events in plain console when log level is debug"() { @@ -422,8 +436,8 @@ renderer.restore(snapshot) // close console to flush then: - output.toString().readLines() == ['10:00:00.000 [INFO] [category] info', '10:00:00.000 [ERROR] [category] error'] - error.toString().empty + output.toString().readLines() == ['10:00:00.000 [INFO] [category] info'] + error.toString().readLines() == ['10:00:00.000 [ERROR] [category] error'] } def "attaches plain console when stdout and stderr are attached"() { @@ -438,8 +452,8 @@ renderer.restore(snapshot) // close console to flush then: - output.toString().readLines() == ['info', 'error'] - error.toString().empty + output.toString().readLines() == ['info'] + error.toString().readLines() == ['error'] outputs.stdOut == '' outputs.stdErr == '' } Index: subprojects/native/src/main/java/org/gradle/internal/nativeintegration/console/FallbackConsoleMetaData.java =================================================================== diff -u -N -rf1cee0faaffba36016f3d88eefa723e7e9d220c1 -r410a52b5b4cf97750f0e1b8fee12f8b63f5665d1 --- subprojects/native/src/main/java/org/gradle/internal/nativeintegration/console/FallbackConsoleMetaData.java (.../FallbackConsoleMetaData.java) (revision f1cee0faaffba36016f3d88eefa723e7e9d220c1) +++ subprojects/native/src/main/java/org/gradle/internal/nativeintegration/console/FallbackConsoleMetaData.java (.../FallbackConsoleMetaData.java) (revision 410a52b5b4cf97750f0e1b8fee12f8b63f5665d1) @@ -17,16 +17,23 @@ package org.gradle.internal.nativeintegration.console; public enum FallbackConsoleMetaData implements ConsoleMetaData { - INSTANCE; + ATTACHED(true), + NOT_ATTACHED(false); + private final boolean attached; + + FallbackConsoleMetaData(boolean attached) { + this.attached = attached; + } + @Override public boolean isStdOut() { - return true; + return attached; } @Override public boolean isStdErr() { - return true; + return attached; } @Override Index: subprojects/native/src/main/java/org/gradle/internal/nativeintegration/console/WindowsConsoleDetector.java =================================================================== diff -u -N -rf1cee0faaffba36016f3d88eefa723e7e9d220c1 -r410a52b5b4cf97750f0e1b8fee12f8b63f5665d1 --- subprojects/native/src/main/java/org/gradle/internal/nativeintegration/console/WindowsConsoleDetector.java (.../WindowsConsoleDetector.java) (revision f1cee0faaffba36016f3d88eefa723e7e9d220c1) +++ subprojects/native/src/main/java/org/gradle/internal/nativeintegration/console/WindowsConsoleDetector.java (.../WindowsConsoleDetector.java) (revision 410a52b5b4cf97750f0e1b8fee12f8b63f5665d1) @@ -27,7 +27,7 @@ // Use Jansi's detection mechanism try { new WindowsAnsiOutputStream(new ByteArrayOutputStream()); - return FallbackConsoleMetaData.INSTANCE; + return FallbackConsoleMetaData.ATTACHED; } catch (IOException ignore) { // Not attached to a console return null; Index: subprojects/tooling-api/src/crossVersionTest/groovy/org/gradle/integtests/tooling/m3/ToolingApiLoggingCrossVersionSpec.groovy =================================================================== diff -u -N -r73da0f113bd7cb8d1345cc5bb3366d31d130e37e -r410a52b5b4cf97750f0e1b8fee12f8b63f5665d1 --- subprojects/tooling-api/src/crossVersionTest/groovy/org/gradle/integtests/tooling/m3/ToolingApiLoggingCrossVersionSpec.groovy (.../ToolingApiLoggingCrossVersionSpec.groovy) (revision 73da0f113bd7cb8d1345cc5bb3366d31d130e37e) +++ subprojects/tooling-api/src/crossVersionTest/groovy/org/gradle/integtests/tooling/m3/ToolingApiLoggingCrossVersionSpec.groovy (.../ToolingApiLoggingCrossVersionSpec.groovy) (revision 410a52b5b4cf97750f0e1b8fee12f8b63f5665d1) @@ -20,44 +20,45 @@ import org.gradle.integtests.tooling.fixture.TestResultHandler import org.gradle.integtests.tooling.fixture.ToolingApiLoggingSpecification import org.gradle.test.fixtures.ConcurrentTestUtil -import org.gradle.test.fixtures.server.http.CyclicBarrierHttpServer +import org.gradle.test.fixtures.server.http.BlockingHttpServer import org.gradle.tooling.ProjectConnection import org.junit.Rule class ToolingApiLoggingCrossVersionSpec extends ToolingApiLoggingSpecification { - @Rule CyclicBarrierHttpServer server = new CyclicBarrierHttpServer() + @Rule BlockingHttpServer server = new BlockingHttpServer() def "logging is live"() { + server.start() def waitingMessage = "logging task: connecting to ${server.uri}" def finishedMessage = "logging task: finished" file("build.gradle") << """ task log { doLast { println "${waitingMessage}" - new URL("${server.uri}").text + ${server.callFromBuild("waiting")} println "${finishedMessage}" } } """ when: def resultHandler = new TestResultHandler() + def sync = server.expectAndBlock("waiting") def output = new TestOutputStream() withConnection { ProjectConnection connection -> def build = connection.newBuild() build.standardOutput = output build.forTasks("log") build.run(resultHandler) - if (server.waitFor(false, 60)) { - ConcurrentTestUtil.poll { - // Need to poll, as logging output is delivered asynchronously to client - assert output.toString().contains(waitingMessage) - } - assert !output.toString().contains(finishedMessage) - server.release() - resultHandler.finished() + sync.waitForAllPendingCalls() + ConcurrentTestUtil.poll { + // Need to poll, as logging output is delivered asynchronously to client + assert output.toString().contains(waitingMessage) } + assert !output.toString().contains(finishedMessage) + sync.releaseAll() + resultHandler.finished() resultHandler.failWithFailure() } Index: subprojects/tooling-api/src/crossVersionTest/groovy/org/gradle/integtests/tooling/m8/ToolingApiLoggingCrossVersionSpec.groovy =================================================================== diff -u -N -rde1b9708f42853fec245e0743f5188ece6314e24 -r410a52b5b4cf97750f0e1b8fee12f8b63f5665d1 --- subprojects/tooling-api/src/crossVersionTest/groovy/org/gradle/integtests/tooling/m8/ToolingApiLoggingCrossVersionSpec.groovy (.../ToolingApiLoggingCrossVersionSpec.groovy) (revision de1b9708f42853fec245e0743f5188ece6314e24) +++ subprojects/tooling-api/src/crossVersionTest/groovy/org/gradle/integtests/tooling/m8/ToolingApiLoggingCrossVersionSpec.groovy (.../ToolingApiLoggingCrossVersionSpec.groovy) (revision 410a52b5b4cf97750f0e1b8fee12f8b63f5665d1) @@ -116,8 +116,7 @@ and: def errLogging - if (targetVersion.baseVersion >= GradleVersion.version("4.7")) { - // Handling of error log message changed + if (targetDist.toolingApiMergesStderrIntoStdout) { errLogging = out } else { errLogging = err @@ -149,19 +148,19 @@ private ExecutionResult runUsingCommandLine() { def executer = targetDist.executer(temporaryFolder, getBuildContext()) .requireGradleDistribution() - .withTestConsoleAttached() .withCommandLineGradleOpts("-Dorg.gradle.deprecation.trace=false") //suppress deprecation stack trace - if (targetVersion.baseVersion >= GradleVersion.version("4.0")) { + if (targetDist.toolingApiMergesStderrIntoStdout) { + // The TAPI provider merges the streams, so need to merge the streams for command-line execution too executer.withArgument("--console=plain") + executer.withTestConsoleAttached() + // We changed the test console system property values in 4.9, need to use "both" instead of "BOTH" + if (targetVersion.baseVersion >= GradleVersion.version("4.8") + && targetVersion.baseVersion < GradleVersion.version("4.9")) { + executer.withCommandLineGradleOpts("-Dorg.gradle.internal.console.test-console=both") + } } - // We changed the test console system property value in 4.9 - if (targetVersion.baseVersion >= GradleVersion.version("4.8") - && targetVersion.baseVersion < GradleVersion.version("4.9")) { - executer.withCommandLineGradleOpts("-Dorg.gradle.internal.console.test-console=both") - } - return executer.run() } Index: subprojects/tooling-api/src/crossVersionTest/groovy/org/gradle/integtests/tooling/r48/PhasedBuildActionCrossVersionSpec.groovy =================================================================== diff -u -N -r738548361560637b7107d7e79ad6ef55d6b910d9 -r410a52b5b4cf97750f0e1b8fee12f8b63f5665d1 --- subprojects/tooling-api/src/crossVersionTest/groovy/org/gradle/integtests/tooling/r48/PhasedBuildActionCrossVersionSpec.groovy (.../PhasedBuildActionCrossVersionSpec.groovy) (revision 738548361560637b7107d7e79ad6ef55d6b910d9) +++ subprojects/tooling-api/src/crossVersionTest/groovy/org/gradle/integtests/tooling/r48/PhasedBuildActionCrossVersionSpec.groovy (.../PhasedBuildActionCrossVersionSpec.groovy) (revision 410a52b5b4cf97750f0e1b8fee12f8b63f5665d1) @@ -162,8 +162,11 @@ and: def failure = OutputScrapingExecutionFailure.from(stdout.toString(), stderr.toString()) - // <5.1 would log an intermediate exception with the actual exception as its cause, >=5.1 log just the actual exception - failure.assertRawOutputContains('actionFailure') + if (targetDist.toolingApiHasCauseOnPhasedActionFail) { + failure.assertHasDescription('actionFailure') + } else { + failure.assertHasCause('actionFailure') + } assertHasConfigureFailedLogging() } Index: subprojects/tooling-api/src/integTest/groovy/org/gradle/integtests/tooling/ConcurrentToolingApiIntegrationSpec.groovy =================================================================== diff -u -N -r5f064f9707a2f40ffaac960beb34943d39d91570 -r410a52b5b4cf97750f0e1b8fee12f8b63f5665d1 --- subprojects/tooling-api/src/integTest/groovy/org/gradle/integtests/tooling/ConcurrentToolingApiIntegrationSpec.groovy (.../ConcurrentToolingApiIntegrationSpec.groovy) (revision 5f064f9707a2f40ffaac960beb34943d39d91570) +++ subprojects/tooling-api/src/integTest/groovy/org/gradle/integtests/tooling/ConcurrentToolingApiIntegrationSpec.groovy (.../ConcurrentToolingApiIntegrationSpec.groovy) (revision 410a52b5b4cf97750f0e1b8fee12f8b63f5665d1) @@ -134,8 +134,8 @@ assert operation.standardOutput.contains("out=hasta la vista $idx") assert operation.standardOutput.count("out=hasta la vista") == 1 - assert operation.standardOutput.contains("err=hasta la vista $idx") - assert operation.standardOutput.count("err=hasta la vista") == 1 + assert operation.standardError.contains("err=hasta la vista $idx") + assert operation.standardError.count("err=hasta la vista") == 1 } } concurrent.finished() @@ -315,13 +315,11 @@ assert operation.standardOutput.contains("this is stdout: $idx") assert operation.standardOutput.count("this is stdout") == 1 - assert operation.standardOutput.contains("this is stderr: $idx") - assert operation.standardOutput.count("this is stderr") == 1 + assert operation.standardError.contains("this is stderr: $idx") + assert operation.standardError.count("this is stderr") == 1 assert operation.standardOutput.contains("this is lifecycle: $idx") assert operation.standardOutput.count("this is lifecycle") == 1 - - assert operation.standardError.empty } } } @@ -351,13 +349,11 @@ assert operation.standardOutput.contains("this is stdout: $idx") assert operation.standardOutput.count("this is stdout") == 1 - assert operation.standardOutput.contains("this is stderr: $idx") - assert operation.standardOutput.count("this is stderr") == 1 + assert operation.standardError.contains("this is stderr: $idx") + assert operation.standardError.count("this is stderr") == 1 assert operation.standardOutput.contains("this is lifecycle: $idx") assert operation.standardOutput.count("this is lifecycle") == 1 - - assert operation.standardError.empty } } } Index: subprojects/tooling-api/src/integTest/groovy/org/gradle/integtests/tooling/GlobalLoggingManipulationIntegrationTest.groovy =================================================================== diff -u -N -r02bb5f9d3d26e66e024b8072f16787e2e239f9fc -r410a52b5b4cf97750f0e1b8fee12f8b63f5665d1 --- subprojects/tooling-api/src/integTest/groovy/org/gradle/integtests/tooling/GlobalLoggingManipulationIntegrationTest.groovy (.../GlobalLoggingManipulationIntegrationTest.groovy) (revision 02bb5f9d3d26e66e024b8072f16787e2e239f9fc) +++ subprojects/tooling-api/src/integTest/groovy/org/gradle/integtests/tooling/GlobalLoggingManipulationIntegrationTest.groovy (.../GlobalLoggingManipulationIntegrationTest.groovy) (revision 410a52b5b4cf97750f0e1b8fee12f8b63f5665d1) @@ -17,7 +17,7 @@ import org.gradle.integtests.fixtures.AbstractIntegrationSpec import org.gradle.integtests.tooling.fixture.ToolingApi -import org.gradle.test.fixtures.server.http.CyclicBarrierHttpServer +import org.gradle.test.fixtures.server.http.BlockingHttpServer import org.gradle.tooling.ProjectConnection import org.gradle.tooling.internal.consumer.BlockingResultHandler import org.gradle.tooling.model.GradleProject @@ -32,11 +32,12 @@ @Rule RedirectStdIn stdIn @Rule - CyclicBarrierHttpServer sync = new CyclicBarrierHttpServer() + BlockingHttpServer sync = new BlockingHttpServer() final ToolingApi toolingApi = new ToolingApi(distribution, temporaryFolder) def setup() { toolingApi.requireIsolatedToolingApi() + sync.start() } def cleanup() { @@ -69,9 +70,10 @@ def outInstance = System.out def errInstance = System.err def inInstance = System.in + def handle = sync.expectAndBlock("waiting") buildFile << """ - new URL("${sync.uri}").text + ${sync.callFromBuild("waiting")} task hey """ @@ -82,11 +84,11 @@ builder.standardOutput = outInstance builder.standardError = errInstance builder.get(handler) - sync.waitFor(60) + handle.waitForAllPendingCalls() assert System.out.is(outInstance) assert System.err.is(errInstance) assert System.in.is(inInstance) - sync.release() + handle.releaseAll() handler.result } @@ -141,9 +143,11 @@ //this gives some confidence that the LogManager was not reset given: toolingApi.requireDaemons() + def handle = sync.expectAndBlock("waiting") + LogManager.getLogManager().getLogger("").setLevel(OFF); buildFile << """ - new URL("${sync.uri}").text + ${sync.callFromBuild("waiting")} task hey """ @@ -155,9 +159,9 @@ builder.standardOutput = System.out builder.standardError = System.err builder.get(handler) - sync.waitFor() + handle.waitForAllPendingCalls() assertJavaUtilLoggingNotModified() - sync.release() + handle.releaseAll() handler.result }