-
Notifications
You must be signed in to change notification settings - Fork 6.1k
8356438: Update OutputAnalyzer to optionally print process output as it happens #25587
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
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -27,6 +27,7 @@ | |
import java.io.ByteArrayOutputStream; | ||
import java.io.InputStream; | ||
import java.io.StringReader; | ||
import java.io.OutputStream; | ||
import java.nio.charset.Charset; | ||
import java.time.Instant; | ||
import java.util.List; | ||
|
@@ -111,10 +112,12 @@ private static class StreamTask { | |
private final Future<Void> future; | ||
private final Charset cs; | ||
|
||
private StreamTask(InputStream stream, Charset cs) { | ||
private StreamTask(InputStream stream, Charset cs, OutputStream additionalStream) { | ||
this.buffer = new ByteArrayOutputStream(); | ||
this.cs = cs; | ||
this.future = new StreamPumper(stream, buffer).process(); | ||
StreamPumper pumper = new StreamPumper(stream, buffer); | ||
if (additionalStream != null) pumper.addOutputStream(additionalStream); | ||
this.future = pumper.process(); | ||
} | ||
|
||
public String get() { | ||
|
@@ -144,8 +147,9 @@ private final void logProgress(String state) { | |
private LazyOutputBuffer(Process p, Charset cs) { | ||
this.p = p; | ||
logProgress("Gathering output"); | ||
outTask = new StreamTask(p.getInputStream(), cs); | ||
errTask = new StreamTask(p.getErrorStream(), cs); | ||
boolean verbose = Boolean.getBoolean("outputanalyzer.verbose"); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. "verbose" is not really the right word here either. This does not change the amount of output only where it also gets sent to, and that is hard-wired to stdout/err so the name should reflect that e.g. I'm not at all sure how to expose this to the top-level API's though. |
||
outTask = new StreamTask(p.getInputStream(), cs, verbose ? System.out : null); | ||
errTask = new StreamTask(p.getErrorStream(), cs, verbose ? System.err : null); | ||
} | ||
|
||
@Override | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Putting a system property at this level of the code kind of hides the functionality.
An alternative solution would be to have
OutputAnalyzer
constructor(s) that takes a boolean argument. That boolean could be set as needed by individual tests using thetest.debug
property already used by a lot of tests.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But isn't it the person running the tests that wants to set this, not an inherent property of a test itself? Or are you envisaging enabling it at the test-level so the person running the tests doesn't have to do so? But then how does that affect the overall jtreg log content. ??
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To add on this, I should mention that I noticed a lot of tests are using OutputAnalyzer indirectly, returned as a result of a utility function, for example
ProcessTools.execute{Process,Command}
Instead of calling one of OutputAnalyzer's constructors (700 invocations, but many of them are with the Eager, string based and not process based, constructor, which we don't care about)
I'm not sure adding additional parameters also to that code is an ideal solution, I'd much prefer adding the command line parameter to the docs of the OutputAnalyzer class, so that one knows to enable it when running the single test through jtreg
That said, if there are multiple OutputAnalyzers going in a single test, then it makes perfect sense to have (or at least use) a constructor argument
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure if I completely understand your question. A lot of tests use the
test.debug
system property to enable more verbose test output. It's enabled when someone runs the test e.g.,jtreg -Dtest.debug=true ...
As you pointed out, a lot of tests may not care if the subprocess's output is cached or not, but for those that do, having to specify a second property could be onerous and using the same
test.debug
property inside OutputBuffer could result in unexpected output. If the OutputAnalyzer ctor took a boolean , a test could enable (or not) with something likenew OutputAnalyzer(childProc, Boolean.getBoolean("test.debug"))
There are two constructors that take Process objects as arguments. I was thinking that you could overload them to take the extra argument.
None of the existing tests would be affected and those tests that could benefit from inline output could specify it as needed. You're right that the use of OutputAnalyzer is usually indirect so that would cause some other code to be changed as well, but it only has to change when it becomes necessary to enable it. (And it can be updated in the same way i.e., overloading the methods to take an extra argument.)