# HG changeset patch # User rschmelter # Date 1564131167 -7200 # Node ID 0a8436eda2fa81c9cf87f6a84b631b3deda0fe51 # Parent 2116221e2dde71aa65dce2e726cd416eee3b7755 8228589: BasicJStackTest.java and JcmdOutputEncodingTest.java failing after JDK-8227868 Reviewed-by: cjplummer, sgehwolf diff -r 2116221e2dde -r 0a8436eda2fa test/jdk/sun/tools/jcmd/JcmdOutputEncodingTest.java --- a/test/jdk/sun/tools/jcmd/JcmdOutputEncodingTest.java Mon Jul 29 08:17:26 2019 +0000 +++ b/test/jdk/sun/tools/jcmd/JcmdOutputEncodingTest.java Fri Jul 26 10:52:47 2019 +0200 @@ -22,6 +22,8 @@ */ import java.util.Arrays; +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; import jdk.test.lib.process.OutputAnalyzer; import jdk.test.lib.process.ProcessTools; @@ -41,17 +43,19 @@ } private static void testThreadDump() throws Exception { - String markerName = "markerName" + "\u00e4\u0bb5".repeat(10_000); - Thread.currentThread().setName(markerName); + String marker = "markerName" + "\u00e4\u0bb5".repeat(60); + Charset cs = StandardCharsets.UTF_8; + Thread.currentThread().setName(marker); JDKToolLauncher launcher = JDKToolLauncher.createUsingTestJDK("jcmd"); + launcher.addVMArg("-Dfile.encoding=" + cs); launcher.addToolArg(Long.toString(ProcessTools.getProcessId())); launcher.addToolArg("Thread.print"); ProcessBuilder processBuilder = new ProcessBuilder(); processBuilder.command(launcher.getCommand()); - OutputAnalyzer output = ProcessTools.executeProcess(processBuilder); + OutputAnalyzer output = ProcessTools.executeProcess(processBuilder, null, cs); output.shouldHaveExitValue(0); - output.shouldContain(markerName); + output.shouldContain(marker); } } diff -r 2116221e2dde -r 0a8436eda2fa test/jdk/sun/tools/jstack/BasicJStackTest.java --- a/test/jdk/sun/tools/jstack/BasicJStackTest.java Mon Jul 29 08:17:26 2019 +0000 +++ b/test/jdk/sun/tools/jstack/BasicJStackTest.java Fri Jul 26 10:52:47 2019 +0200 @@ -22,6 +22,8 @@ */ import java.util.Arrays; +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; import jdk.test.lib.process.OutputAnalyzer; import jdk.test.lib.process.ProcessTools; @@ -36,29 +38,40 @@ public class BasicJStackTest { private static ProcessBuilder processBuilder = new ProcessBuilder(); - private static String markerName = "markerName" + "\u00e4\u0bb5".repeat(10_000); public static void main(String[] args) throws Exception { testJstackNoArgs(); testJstack_l(); + testJstackUTF8Encoding(); } private static void testJstackNoArgs() throws Exception { - OutputAnalyzer output = jstack(); + String marker = "testJstackNoArgs"; + OutputAnalyzer output = jstack(marker); output.shouldHaveExitValue(0); - output.shouldContain(markerName); + output.shouldContain(marker); } private static void testJstack_l() throws Exception { - OutputAnalyzer output = jstack("-l"); + String marker = "testJstack_l"; + OutputAnalyzer output = jstack(marker, "-l"); output.shouldHaveExitValue(0); - output.shouldContain(markerName); + output.shouldContain(marker); } - private static OutputAnalyzer jstack(String... toolArgs) throws Exception { - Thread.currentThread().setName(markerName); + private static void testJstackUTF8Encoding() throws Exception { + String marker = "markerName" + "\u00e4\u0bb5".repeat(60); + OutputAnalyzer output = jstack(marker); + output.shouldHaveExitValue(0); + output.shouldContain(marker); + } + + private static OutputAnalyzer jstack(String marker, String... toolArgs) throws Exception { + Charset cs = StandardCharsets.UTF_8; + Thread.currentThread().setName(marker); JDKToolLauncher launcher = JDKToolLauncher.createUsingTestJDK("jstack"); launcher.addVMArg("-XX:+UsePerfData"); + launcher.addVMArg("-Dfile.encoding=" + cs); if (toolArgs != null) { for (String toolArg : toolArgs) { launcher.addToolArg(toolArg); @@ -68,7 +81,7 @@ processBuilder.command(launcher.getCommand()); System.out.println(Arrays.toString(processBuilder.command().toArray()).replace(",", "")); - OutputAnalyzer output = ProcessTools.executeProcess(processBuilder); + OutputAnalyzer output = ProcessTools.executeProcess(processBuilder, null, cs); System.out.println(output.getOutput()); return output; diff -r 2116221e2dde -r 0a8436eda2fa test/lib/jdk/test/lib/process/OutputAnalyzer.java --- a/test/lib/jdk/test/lib/process/OutputAnalyzer.java Mon Jul 29 08:17:26 2019 +0000 +++ b/test/lib/jdk/test/lib/process/OutputAnalyzer.java Fri Jul 26 10:52:47 2019 +0200 @@ -27,6 +27,7 @@ import java.io.IOException; import java.io.PrintStream; +import java.nio.charset.Charset; import java.nio.file.Files; import java.nio.file.Path; import java.util.Arrays; @@ -43,6 +44,18 @@ * value from a Process * * @param process Process to analyze + * @param cs The charset used to convert stdout/stderr from bytes to chars + * or null for the default charset. + * @throws IOException If an I/O error occurs. + */ + public OutputAnalyzer(Process process, Charset cs) throws IOException { + buffer = OutputBuffer.of(process, cs); + } + /** + * Create an OutputAnalyzer, a utility class for verifying output and exit + * value from a Process + * + * @param process Process to analyze * @throws IOException If an I/O error occurs. */ public OutputAnalyzer(Process process) throws IOException { diff -r 2116221e2dde -r 0a8436eda2fa test/lib/jdk/test/lib/process/OutputBuffer.java --- a/test/lib/jdk/test/lib/process/OutputBuffer.java Mon Jul 29 08:17:26 2019 +0000 +++ b/test/lib/jdk/test/lib/process/OutputBuffer.java Fri Jul 26 10:52:47 2019 +0200 @@ -25,6 +25,7 @@ import java.io.ByteArrayOutputStream; import java.io.InputStream; +import java.nio.charset.Charset; import java.time.Instant; import java.util.concurrent.CancellationException; import java.util.concurrent.ExecutionException; @@ -53,8 +54,12 @@ public String getStderr(); public int getExitValue(); + public static OutputBuffer of(Process p, Charset cs) { + return new LazyOutputBuffer(p, cs); + } + public static OutputBuffer of(Process p) { - return new LazyOutputBuffer(p); + return new LazyOutputBuffer(p, null); } public static OutputBuffer of(String stdout, String stderr, int exitValue) { @@ -69,16 +74,18 @@ private static class StreamTask { private final ByteArrayOutputStream buffer; private final Future future; + private final Charset cs; - private StreamTask(InputStream stream) { + private StreamTask(InputStream stream, Charset cs) { this.buffer = new ByteArrayOutputStream(); + this.cs = cs; this.future = new StreamPumper(stream, buffer).process(); } public String get() { try { future.get(); - return buffer.toString(); + return cs == null ? buffer.toString() : buffer.toString(cs); } catch (InterruptedException e) { Thread.currentThread().interrupt(); throw new OutputBufferException(e); @@ -98,11 +105,11 @@ System.out.flush(); } - private LazyOutputBuffer(Process p) { + private LazyOutputBuffer(Process p, Charset cs) { this.p = p; logProgress("Gathering output"); - outTask = new StreamTask(p.getInputStream()); - errTask = new StreamTask(p.getErrorStream()); + outTask = new StreamTask(p.getInputStream(), cs); + errTask = new StreamTask(p.getErrorStream(), cs); } @Override diff -r 2116221e2dde -r 0a8436eda2fa test/lib/jdk/test/lib/process/ProcessTools.java --- a/test/lib/jdk/test/lib/process/ProcessTools.java Mon Jul 29 08:17:26 2019 +0000 +++ b/test/lib/jdk/test/lib/process/ProcessTools.java Fri Jul 26 10:52:47 2019 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2019, 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 @@ -27,6 +27,7 @@ import java.io.InputStream; import java.io.OutputStream; import java.io.PrintStream; +import java.nio.charset.Charset; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; @@ -359,6 +360,21 @@ * @return The {@linkplain OutputAnalyzer} instance wrapping the process. */ public static OutputAnalyzer executeProcess(ProcessBuilder pb, String input) throws Exception { + return executeProcess(pb, null, null); + } + + /** + * Executes a process, pipe some text into its STDIN, waits for it + * to finish and returns the process output. The process will have exited + * before this method returns. + * @param pb The ProcessBuilder to execute. + * @param input The text to pipe into STDIN. Can be null. + * @param cs The charset used to convert from bytes to chars or null for + * the default charset. + * @return The {@linkplain OutputAnalyzer} instance wrapping the process. + */ + public static OutputAnalyzer executeProcess(ProcessBuilder pb, String input, + Charset cs) throws Exception { OutputAnalyzer output = null; Process p = null; boolean failed = false; @@ -370,7 +386,7 @@ } } - output = new OutputAnalyzer(p); + output = new OutputAnalyzer(p, cs); p.waitFor(); return output;