Skip to content

Commit ae181c8

Browse files
committed
Enable auto-flushing of output to fix testfeed details mode (#4153)
Prior to this commit, `ConsoleLauncher` created `PrintWriters` that wouldn't flush automatically when `println` is called which stopped the `testfeed` details mode from being useful. Moreover, it didn't initialized them with the right `Charsets`. Now, we rely on Picocli's initialization again which does both correctly. (cherry picked from commit b8b5dc4)
1 parent f275a8f commit ae181c8

File tree

7 files changed

+93
-60
lines changed

7 files changed

+93
-60
lines changed

gradle/plugins/common/src/main/kotlin/junitbuild/exec/RunConsoleLauncher.kt

+16-2
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,13 @@ import org.gradle.api.file.ConfigurableFileCollection
66
import org.gradle.api.plugins.JavaPluginExtension
77
import org.gradle.api.provider.ListProperty
88
import org.gradle.api.provider.Property
9-
import org.gradle.api.tasks.*
9+
import org.gradle.api.tasks.CacheableTask
10+
import org.gradle.api.tasks.Classpath
11+
import org.gradle.api.tasks.Input
12+
import org.gradle.api.tasks.Internal
13+
import org.gradle.api.tasks.Nested
14+
import org.gradle.api.tasks.SourceSetContainer
15+
import org.gradle.api.tasks.TaskAction
1016
import org.gradle.api.tasks.options.Option
1117
import org.gradle.jvm.toolchain.JavaLauncher
1218
import org.gradle.jvm.toolchain.JavaToolchainService
@@ -16,7 +22,6 @@ import org.gradle.process.CommandLineArgumentProvider
1622
import org.gradle.process.ExecOperations
1723
import trackOperationSystemAsInput
1824
import java.io.ByteArrayOutputStream
19-
import java.util.*
2025
import javax.inject.Inject
2126

2227
@CacheableTask
@@ -97,4 +102,13 @@ abstract class RunConsoleLauncher @Inject constructor(private val execOperations
97102
debugging.set(enabled)
98103
}
99104

105+
@Suppress("unused")
106+
@Option(
107+
option = "show-output",
108+
description = "Show output"
109+
)
110+
fun setShowOutput(showOutput: Boolean) {
111+
hideOutput.set(!showOutput)
112+
}
113+
100114
}

junit-platform-console/src/main/java/org/junit/platform/console/ConsoleLauncher.java

+4-23
Original file line numberDiff line numberDiff line change
@@ -30,36 +30,17 @@
3030
public class ConsoleLauncher {
3131

3232
public static void main(String... args) {
33-
PrintWriter out = new PrintWriter(System.out);
34-
PrintWriter err = new PrintWriter(System.err);
35-
CommandResult<?> result = run(out, err, args);
33+
CommandResult<?> result = newCommandFacade().run(args);
3634
System.exit(result.getExitCode());
3735
}
3836

3937
@API(status = INTERNAL, since = "1.0")
4038
public static CommandResult<?> run(PrintWriter out, PrintWriter err, String... args) {
41-
ConsoleLauncher consoleLauncher = new ConsoleLauncher(ConsoleTestExecutor::new, out, err);
42-
return consoleLauncher.run(args);
39+
return newCommandFacade().run(args, out, err);
4340
}
4441

45-
private final ConsoleTestExecutor.Factory consoleTestExecutorFactory;
46-
private final PrintWriter out;
47-
private final PrintWriter err;
48-
49-
ConsoleLauncher(ConsoleTestExecutor.Factory consoleTestExecutorFactory, PrintWriter out, PrintWriter err) {
50-
this.consoleTestExecutorFactory = consoleTestExecutorFactory;
51-
this.out = out;
52-
this.err = err;
53-
}
54-
55-
CommandResult<?> run(String... args) {
56-
try {
57-
return new CommandFacade(consoleTestExecutorFactory).run(out, err, args);
58-
}
59-
finally {
60-
out.flush();
61-
err.flush();
62-
}
42+
private static CommandFacade newCommandFacade() {
43+
return new CommandFacade(ConsoleTestExecutor::new);
6344
}
6445

6546
}

junit-platform-console/src/main/java/org/junit/platform/console/options/CommandFacade.java

+16-2
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,24 @@ public CommandFacade(ConsoleTestExecutor.Factory consoleTestExecutorFactory) {
3333
this.consoleTestExecutorFactory = consoleTestExecutorFactory;
3434
}
3535

36-
public CommandResult<?> run(PrintWriter out, PrintWriter err, String[] args) {
36+
public CommandResult<?> run(String[] args) {
37+
return run(args, Optional.empty());
38+
}
39+
40+
public CommandResult<?> run(String[] args, PrintWriter out, PrintWriter err) {
41+
try {
42+
return run(args, Optional.of(new OutputStreamConfig(out, err)));
43+
}
44+
finally {
45+
out.flush();
46+
err.flush();
47+
}
48+
}
49+
50+
private CommandResult<?> run(String[] args, Optional<OutputStreamConfig> outputStreamConfig) {
3751
Optional<String> version = ManifestVersionProvider.getImplementationVersion();
3852
System.setProperty("junit.docs.version",
3953
version.map(it -> it.endsWith("-SNAPSHOT") ? "snapshot" : it).orElse("current"));
40-
return new MainCommand(consoleTestExecutorFactory).run(out, err, args);
54+
return new MainCommand(consoleTestExecutorFactory).run(args, outputStreamConfig);
4155
}
4256
}

junit-platform-console/src/main/java/org/junit/platform/console/options/MainCommand.java

+11-15
Original file line numberDiff line numberDiff line change
@@ -103,10 +103,11 @@ private Object runCommand(String subcommand, Optional<String> triggeringOption)
103103

104104
List<String> args = new ArrayList<>(commandLine.getParseResult().expandedArgs());
105105
triggeringOption.ifPresent(args::remove);
106-
CommandResult<?> result = runCommand(commandLine.getOut(), //
107-
commandLine.getErr(), //
106+
CommandResult<?> result = runCommand( //
107+
new CommandLine(command), //
108108
args.toArray(new String[0]), //
109-
command);
109+
Optional.of(new OutputStreamConfig(commandLine)) //
110+
);
110111
this.commandResult = result;
111112

112113
printDeprecationWarning(subcommand, triggeringOption, commandLine);
@@ -130,24 +131,19 @@ private static void printDeprecationWarning(String subcommand, Optional<String>
130131
err.flush();
131132
}
132133

133-
CommandResult<?> run(PrintWriter out, PrintWriter err, String[] args) {
134+
CommandResult<?> run(String[] args, Optional<OutputStreamConfig> outputStreamConfig) {
134135
CommandLine commandLine = new CommandLine(this) //
135136
.addSubcommand(new DiscoverTestsCommand(consoleTestExecutorFactory)) //
136137
.addSubcommand(new ExecuteTestsCommand(consoleTestExecutorFactory)) //
137138
.addSubcommand(new ListTestEnginesCommand());
138-
return runCommand(out, err, args, commandLine);
139+
return runCommand(commandLine, args, outputStreamConfig);
139140
}
140141

141-
private static CommandResult<?> runCommand(PrintWriter out, PrintWriter err, String[] args, Object command) {
142-
return runCommand(out, err, args, new CommandLine(command));
143-
}
144-
145-
private static CommandResult<Object> runCommand(PrintWriter out, PrintWriter err, String[] args,
146-
CommandLine commandLine) {
147-
int exitCode = BaseCommand.initialize(commandLine) //
148-
.setOut(out) //
149-
.setErr(err) //
150-
.execute(args);
142+
private static CommandResult<?> runCommand(CommandLine commandLine, String[] args,
143+
Optional<OutputStreamConfig> outputStreamConfig) {
144+
BaseCommand.initialize(commandLine);
145+
outputStreamConfig.ifPresent(it -> it.applyTo(commandLine));
146+
int exitCode = commandLine.execute(args);
151147
return CommandResult.create(exitCode, getLikelyExecutedCommand(commandLine).getExecutionResult());
152148
}
153149

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
/*
2+
* Copyright 2015-2024 the original author or authors.
3+
*
4+
* All rights reserved. This program and the accompanying materials are
5+
* made available under the terms of the Eclipse Public License v2.0 which
6+
* accompanies this distribution and is available at
7+
*
8+
* https://www.eclipse.org/legal/epl-v20.html
9+
*/
10+
11+
package org.junit.platform.console.options;
12+
13+
import java.io.PrintWriter;
14+
15+
import picocli.CommandLine;
16+
17+
class OutputStreamConfig {
18+
19+
private final PrintWriter out;
20+
private final PrintWriter err;
21+
22+
OutputStreamConfig(CommandLine commandLine) {
23+
this(commandLine.getOut(), commandLine.getErr());
24+
}
25+
26+
OutputStreamConfig(PrintWriter out, PrintWriter err) {
27+
this.out = out;
28+
this.err = err;
29+
}
30+
31+
void applyTo(CommandLine commandLine) {
32+
commandLine.setOut(out).setErr(err);
33+
}
34+
}

platform-tests/src/test/java/org/junit/platform/console/ConsoleLauncherTests.java

+6-13
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222
import org.junit.jupiter.params.provider.Arguments;
2323
import org.junit.jupiter.params.provider.EmptySource;
2424
import org.junit.jupiter.params.provider.MethodSource;
25-
import org.junit.platform.console.tasks.ConsoleTestExecutor;
2625

2726
/**
2827
* @since 1.0
@@ -36,8 +35,7 @@ class ConsoleLauncherTests {
3635
@EmptySource
3736
@MethodSource("commandsWithEmptyOptionExitCodes")
3837
void displayHelp(String command) {
39-
var consoleLauncher = new ConsoleLauncher(ConsoleTestExecutor::new, printSink, printSink);
40-
var exitCode = consoleLauncher.run(command, "--help").getExitCode();
38+
var exitCode = ConsoleLauncher.run(printSink, printSink, command, "--help").getExitCode();
4139

4240
assertEquals(0, exitCode);
4341
assertThat(output()).contains("--help");
@@ -47,8 +45,7 @@ void displayHelp(String command) {
4745
@EmptySource
4846
@MethodSource("commandsWithEmptyOptionExitCodes")
4947
void displayVersion(String command) {
50-
var consoleLauncher = new ConsoleLauncher(ConsoleTestExecutor::new, printSink, printSink);
51-
var exitCode = consoleLauncher.run(command, "--version").getExitCode();
48+
var exitCode = ConsoleLauncher.run(printSink, printSink, command, "--version").getExitCode();
5249

5350
assertEquals(0, exitCode);
5451
assertThat(output()).contains("JUnit Platform Console Launcher");
@@ -57,17 +54,15 @@ void displayVersion(String command) {
5754
@ParameterizedTest(name = "{0}")
5855
@MethodSource("commandsWithEmptyOptionExitCodes")
5956
void displayBanner(String command) {
60-
var consoleLauncher = new ConsoleLauncher(ConsoleTestExecutor::new, printSink, printSink);
61-
consoleLauncher.run(command);
57+
ConsoleLauncher.run(printSink, printSink, command);
6258

6359
assertThat(output()).contains("Thanks for using JUnit!");
6460
}
6561

6662
@ParameterizedTest(name = "{0}")
6763
@MethodSource("commandsWithEmptyOptionExitCodes")
6864
void disableBanner(String command, int expectedExitCode) {
69-
var consoleLauncher = new ConsoleLauncher(ConsoleTestExecutor::new, printSink, printSink);
70-
var exitCode = consoleLauncher.run(command, "--disable-banner").getExitCode();
65+
var exitCode = ConsoleLauncher.run(printSink, printSink, command, "--disable-banner").getExitCode();
7166

7267
assertEquals(expectedExitCode, exitCode);
7368
assertThat(output()).doesNotContain("Thanks for using JUnit!");
@@ -76,8 +71,7 @@ void disableBanner(String command, int expectedExitCode) {
7671
@ParameterizedTest(name = "{0}")
7772
@MethodSource("commandsWithEmptyOptionExitCodes")
7873
void executeWithUnknownCommandLineOption(String command) {
79-
var consoleLauncher = new ConsoleLauncher(ConsoleTestExecutor::new, printSink, printSink);
80-
var exitCode = consoleLauncher.run(command, "--all").getExitCode();
74+
var exitCode = ConsoleLauncher.run(printSink, printSink, command, "--all").getExitCode();
8175

8276
assertEquals(-1, exitCode);
8377
assertThat(output()).contains("Unknown option: '--all'").contains("Usage:");
@@ -90,8 +84,7 @@ private String output() {
9084
@ParameterizedTest(name = "{0}")
9185
@MethodSource("commandsWithEmptyOptionExitCodes")
9286
void executeWithoutCommandLineOptions(String command, int expectedExitCode) {
93-
var consoleLauncher = new ConsoleLauncher(ConsoleTestExecutor::new, printSink, printSink);
94-
var actualExitCode = consoleLauncher.run(command).getExitCode();
87+
var actualExitCode = ConsoleLauncher.run(printSink, printSink, command).getExitCode();
9588

9689
assertEquals(expectedExitCode, actualExitCode);
9790
}

platform-tests/src/test/java/org/junit/platform/console/ConsoleLauncherWrapper.java

+6-5
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
import java.io.StringWriter;
1818
import java.util.Optional;
1919

20+
import org.junit.platform.console.options.CommandFacade;
2021
import org.junit.platform.console.tasks.ConsoleTestExecutor;
2122

2223
/**
@@ -26,16 +27,14 @@ class ConsoleLauncherWrapper {
2627

2728
private final StringWriter out = new StringWriter();
2829
private final StringWriter err = new StringWriter();
29-
private final ConsoleLauncher consoleLauncher;
30+
private final ConsoleTestExecutor.Factory consoleTestExecutorFactory;
3031

3132
ConsoleLauncherWrapper() {
3233
this(ConsoleTestExecutor::new);
3334
}
3435

3536
private ConsoleLauncherWrapper(ConsoleTestExecutor.Factory consoleTestExecutorFactory) {
36-
var outWriter = new PrintWriter(out, false);
37-
var errWriter = new PrintWriter(err, false);
38-
this.consoleLauncher = new ConsoleLauncher(consoleTestExecutorFactory, outWriter, errWriter);
37+
this.consoleTestExecutorFactory = consoleTestExecutorFactory;
3938
}
4039

4140
public ConsoleLauncherWrapperResult execute(String... args) {
@@ -47,7 +46,9 @@ public ConsoleLauncherWrapperResult execute(int expectedExitCode, String... args
4746
}
4847

4948
public ConsoleLauncherWrapperResult execute(Optional<Integer> expectedCode, String... args) {
50-
var result = consoleLauncher.run(args);
49+
var outWriter = new PrintWriter(out, false);
50+
var errWriter = new PrintWriter(err, false);
51+
var result = new CommandFacade(consoleTestExecutorFactory).run(args, outWriter, errWriter);
5152
var code = result.getExitCode();
5253
var outText = out.toString();
5354
var errText = err.toString();

0 commit comments

Comments
 (0)