I’m creating a library that is wrapper around an old library that is printing a lot of stuff directly to ‘System.out’.
So, I’m trying to test it through capturing standard output stream by creating a tee output stream around ‘System.out’ and then asserting on collected data in the end (see example code below).
It all works great in IDE and through local (Windows) Gradle build. But on CI server (RedHat + Jenkins) it seems to loose connection to System.out after 2nd test (i.e. nothing is captured inside test, but JUnit report still shows full stdout correclty) and that’s why assertions fail.
I understand that Gradle does its own capturing of standard output and after some digging I have found that Gradle uses ‘LinePerThreadBufferingOutputStream’, but I’m not sure how to connect that to my problem.
Any ideas what can make the test below also capture the standard output on Linux in the 2nd test?
class LauncherTest extends BaseGeneratorTestCase {
static ByteArrayOutputStream stdOutData
static ByteArrayOutputStream stdErrData
@BeforeClass
static void captureOutput() {
stdOutData = new ByteArrayOutputStream()
stdErrData = new ByteArrayOutputStream()
System.out = new TeeStream(System.out, new PrintStream(stdOutData))
System.err = new TeeStream(System.err, new PrintStream(stdErrData))
}
@Test
// This works
void testExecution1() {
String output = captureOutput {
// execute test code
…
}
// assert on output
…
}
@Test
// This fails on Linux, but works on Windows
void testExecution2() {
String output = captureOutput {
// execute test code
…
}
// assert on output
…
}
static String captureOutput(Closure cl) {
cl()
System.out.flush()
System.err.flush()
stdOutData.flush()
stdErrData.flush()
new String(stdOutData.toByteArray()) + new String(stdErrData.toByteArray())
}
static class TeeStream extends PrintStream {
PrintStream out
TeeStream(PrintStream out1, PrintStream out2) {
super(out1)
this.out = out2
}
void write(byte[] buf, int off, int len) {
super.write(buf, off, len)
out.write(buf, off, len)
}
void write(int b) {
super.write(b)
out.write(b)
}
void close() {
super.close()
out.close()
}
void flush() {
super.flush()
out.flush()
}
}
}