8303697: ProcessTools doesn't print last line of process output
Reviewed-by: dholmes, stuefe
This commit is contained in:
parent
d5a150706e
commit
8d2ebf248e
@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8303697
|
||||
* @summary Test verifies that ProcessTools.startProcess() print all lines even the last line doesn't end with '\n'
|
||||
* @library /test/lib
|
||||
* @run main ProcessToolsLastLineTest
|
||||
*/
|
||||
|
||||
import jdk.test.lib.process.ProcessTools;
|
||||
import jdk.test.lib.Asserts;
|
||||
|
||||
public class ProcessToolsLastLineTest {
|
||||
|
||||
static void test(String output) throws Exception {
|
||||
final StringBuffer sb = new StringBuffer();
|
||||
Process p = ProcessTools.startProcess("process",
|
||||
ProcessTools.createJavaProcessBuilder(ProcessToolsLastLineTest.class.getName(), output),
|
||||
line -> { sb.append(line);});
|
||||
p.waitFor();
|
||||
String expectedOutput = output.replace("\n", "");
|
||||
Asserts.assertEQ(sb.toString(), expectedOutput);
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
|
||||
// The line which exceeds internal StreamPumper buffer (256 bytes)
|
||||
String VERY_LONG_LINE = "X".repeat(257);
|
||||
if (args.length > 0) {
|
||||
System.out.print(args[0]);
|
||||
} else {
|
||||
test("\n");
|
||||
test("\nARG1");
|
||||
test("\nARG1\n");
|
||||
test("ARG1\n");
|
||||
test("ARG1");
|
||||
test("ARG1\nARG2");
|
||||
test("ARG1\nARG2\n");
|
||||
test("\nARG1\nARG2\n");
|
||||
test("\nARG1\n" + VERY_LONG_LINE + "\nARG2\n");
|
||||
test("\nARG1\n" + VERY_LONG_LINE);
|
||||
test("\nARG1\n" + VERY_LONG_LINE + VERY_LONG_LINE + VERY_LONG_LINE + "\nARG2\n");
|
||||
test("\nARG1\n" + VERY_LONG_LINE + VERY_LONG_LINE + VERY_LONG_LINE);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2013, 2023, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -95,13 +95,15 @@ public final class StreamPumper implements Runnable {
|
||||
|
||||
/**
|
||||
* Implements Thread.run(). Continuously read from {@code in} and write to
|
||||
* {@code out} until {@code in} has reached end of stream. Abort on
|
||||
* interruption. Abort on IOExceptions.
|
||||
* {@code out} until {@code in} has reached end of stream.
|
||||
* Additionally this method also splits the data read from the buffer into lines,
|
||||
* and processes each line using linePumps.
|
||||
* Abort on interruption. Abort on IOExceptions.
|
||||
*/
|
||||
@Override
|
||||
public void run() {
|
||||
try (BufferedInputStream is = new BufferedInputStream(in)) {
|
||||
ByteArrayOutputStream lineBos = new ByteArrayOutputStream();
|
||||
try (BufferedInputStream is = new BufferedInputStream(in);
|
||||
ByteArrayOutputStream lineBos = new ByteArrayOutputStream()) {
|
||||
byte[] buf = new byte[BUF_SIZE];
|
||||
int len = 0;
|
||||
int linelen = 0;
|
||||
@ -133,6 +135,10 @@ public final class StreamPumper implements Runnable {
|
||||
|
||||
i++;
|
||||
}
|
||||
// If no crlf was found, or there was additional data after the last crlf was found, then write the leftover data
|
||||
// in lineBos. If there is more data to read it will be concatenated with the current data on the next iteration.
|
||||
// If there is no more data, or no more crlf found, all the remaining data will be processed after the loop, as the
|
||||
// final line.
|
||||
if (lastcrlf == -1) {
|
||||
lineBos.write(buf, 0, len);
|
||||
linelen += len;
|
||||
@ -143,6 +149,12 @@ public final class StreamPumper implements Runnable {
|
||||
}
|
||||
}
|
||||
|
||||
// If there was no terminating crlf the remaining data has been written to lineBos,
|
||||
// but this final line of data now needs to be processed by the linePumper.
|
||||
final String line = lineBos.toString();
|
||||
if (!line.isEmpty()) {
|
||||
linePumps.forEach((lp) -> lp.processLine(line));
|
||||
}
|
||||
} catch (IOException e) {
|
||||
if (!e.getMessage().equalsIgnoreCase("stream closed")) {
|
||||
e.printStackTrace();
|
||||
|
Loading…
Reference in New Issue
Block a user