提交 fcb6500b 编写于 作者: C ctornqvi

8006413: Add utility classes for writing better multiprocess tests in jtreg

Summary: Add a few utility classes to test/testlibrary to support multi process testing in jtreg tests. Added a test case for one of the utility classes. Also reviewed by Vitaly Davidovich
Reviewed-by: brutisso, dholmes, vlivanov, nloodin, mgerdin
上级 a3031899
/*
* Copyright (c) 2013, 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
* @summary Test the OutputAnalyzer utility class
* @library /testlibrary
*/
import com.oracle.java.testlibrary.OutputAnalyzer;
public class OutputAnalyzerTest {
public static void main(String args[]) throws Exception {
String stdout = "aaaaaa";
String stderr = "bbbbbb";
OutputAnalyzer output = new OutputAnalyzer(stdout, stderr);
if (!stdout.equals(output.getStdout())) {
throw new Exception("getStdout() returned '" + output.getStdout() + "', expected '" + stdout + "'");
}
if (!stderr.equals(output.getStderr())) {
throw new Exception("getStderr() returned '" + output.getStderr() + "', expected '" + stderr + "'");
}
try {
output.shouldContain(stdout);
output.stdoutShouldContain(stdout);
output.shouldContain(stderr);
output.stderrShouldContain(stderr);
} catch (RuntimeException e) {
throw new Exception("shouldContain() failed", e);
}
try {
output.shouldContain("cccc");
throw new Exception("shouldContain() failed to throw exception");
} catch (RuntimeException e) {
// expected
}
try {
output.stdoutShouldContain(stderr);
throw new Exception("stdoutShouldContain() failed to throw exception");
} catch (RuntimeException e) {
// expected
}
try {
output.stderrShouldContain(stdout);
throw new Exception("stdoutShouldContain() failed to throw exception");
} catch (RuntimeException e) {
// expected
}
try {
output.shouldNotContain("cccc");
output.stdoutShouldNotContain("cccc");
output.stderrShouldNotContain("cccc");
} catch (RuntimeException e) {
throw new Exception("shouldNotContain() failed", e);
}
try {
output.shouldNotContain(stdout);
throw new Exception("shouldContain() failed to throw exception");
} catch (RuntimeException e) {
// expected
}
try {
output.stdoutShouldNotContain(stdout);
throw new Exception("shouldContain() failed to throw exception");
} catch (RuntimeException e) {
// expected
}
try {
output.stderrShouldNotContain(stderr);
throw new Exception("shouldContain() failed to throw exception");
} catch (RuntimeException e) {
// expected
}
}
}
/*
* Copyright (c) 2013, 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.
*/
package com.oracle.java.testlibrary;
import java.io.File;
public final class JDKToolFinder {
private JDKToolFinder() {
}
/**
* Returns the full path to an executable in jdk/bin based on System property
* test.jdk (set by jtreg test suite)
*
* @return Full path to an executable in jdk/bin
*/
public static String getJDKTool(String tool) {
String binPath = System.getProperty("test.jdk");
if (binPath == null) {
throw new RuntimeException("System property 'test.jdk' not set. This property is normally set by jtreg. "
+ "When running test separately, set this property using '-Dtest.jdk=/path/to/jdk'.");
}
binPath += File.separatorChar + "bin" + File.separatorChar + tool;
return binPath;
}
}
/*
* Copyright (c) 2013, 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.
*/
package com.oracle.java.testlibrary;
import java.io.IOException;
public final class OutputAnalyzer {
private final String stdout;
private final String stderr;
private final int exitValue;
/**
* 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 {
OutputBuffer output = ProcessTools.getOutput(process);
exitValue = process.exitValue();
this.stdout = output.getStdout();
this.stderr = output.getStderr();
}
/**
* Create an OutputAnalyzer, a utility class for verifying output
*
* @param buf String buffer to analyze
*/
public OutputAnalyzer(String buf) {
this(buf, buf);
}
/**
* Create an OutputAnalyzer, a utility class for verifying output
*
* @param stdout stdout buffer to analyze
* @param stderr stderr buffer to analyze
*/
public OutputAnalyzer(String stdout, String stderr) {
this.stdout = stdout;
this.stderr = stderr;
exitValue = -1;
}
/**
* Verify that the stdout and stderr contents of output buffer contains the string
*
* @param expectedString String that buffer should contain
* @throws RuntimeException If the string was not found
*/
public void shouldContain(String expectedString) {
if (!stdout.contains(expectedString) && !stderr.contains(expectedString)) {
throw new RuntimeException("'" + expectedString + "' missing from stdout/stderr: [" + stdout + stderr + "]\n");
}
}
/**
* Verify that the stdout contents of output buffer contains the string
*
* @param expectedString String that buffer should contain
* @throws RuntimeException If the string was not found
*/
public void stdoutShouldContain(String expectedString) {
if (!stdout.contains(expectedString)) {
throw new RuntimeException("'" + expectedString + "' missing from stdout: [" + stdout + "]\n");
}
}
/**
* Verify that the stderr contents of output buffer contains the string
*
* @param expectedString String that buffer should contain
* @throws RuntimeException If the string was not found
*/
public void stderrShouldContain(String expectedString) {
if (!stderr.contains(expectedString)) {
throw new RuntimeException("'" + expectedString + "' missing from stderr: [" + stderr + "]\n");
}
}
/**
* Verify that the stdout and stderr contents of output buffer does not contain the string
*
* @param expectedString String that the buffer should not contain
* @throws RuntimeException If the string was found
*/
public void shouldNotContain(String notExpectedString) {
if (stdout.contains(notExpectedString)) {
throw new RuntimeException("'" + notExpectedString + "' found in stdout: [" + stdout + "]\n");
}
if (stderr.contains(notExpectedString)) {
throw new RuntimeException("'" + notExpectedString + "' found in stderr: [" + stderr + "]\n");
}
}
/**
* Verify that the stdout contents of output buffer does not contain the string
*
* @param expectedString String that the buffer should not contain
* @throws RuntimeException If the string was found
*/
public void stdoutShouldNotContain(String notExpectedString) {
if (stdout.contains(notExpectedString)) {
throw new RuntimeException("'" + notExpectedString + "' found in stdout: [" + stdout + "]\n");
}
}
/**
* Verify that the stderr contents of output buffer does not contain the string
*
* @param expectedString String that the buffer should not contain
* @throws RuntimeException If the string was found
*/
public void stderrShouldNotContain(String notExpectedString) {
if (stderr.contains(notExpectedString)) {
throw new RuntimeException("'" + notExpectedString + "' found in stderr: [" + stderr + "]\n");
}
}
/**
* Verifiy the exit value of the process
*
* @param expectedExitValue Expected exit value from process
* @throws RuntimeException If the exit value from the process did not match the expected value
*/
public void shouldHaveExitValue(int expectedExitValue) {
if (getExitValue() != expectedExitValue) {
throw new RuntimeException("Exit value " + getExitValue() + " , expected to get " + expectedExitValue);
}
}
/**
* Get the contents of the output buffer (stdout and stderr)
*
* @return Content of the output buffer
*/
public String getOutput() {
return stdout + stderr;
}
/**
* Get the contents of the stdout buffer
*
* @return Content of the stdout buffer
*/
public String getStdout() {
return stdout;
}
/**
* Get the contents of the stderr buffer
*
* @return Content of the stderr buffer
*/
public String getStderr() {
return stderr;
}
/**
* Get the process exit value
*
* @return Process exit value
*/
public int getExitValue() {
return exitValue;
}
}
/*
* Copyright (c) 2013, 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.
*/
package com.oracle.java.testlibrary;
public class OutputBuffer {
private final String stdout;
private final String stderr;
/**
* Create an OutputBuffer, a class for storing and managing stdout and stderr
* results separately
*
* @param stdout stdout result
* @param stderr stderr result
*/
public OutputBuffer(String stdout, String stderr) {
this.stdout = stdout;
this.stderr = stderr;
}
/**
* Returns the stdout result
*
* @return stdout result
*/
public String getStdout() {
return stdout;
}
/**
* Returns the stderr result
*
* @return stderr result
*/
public String getStderr() {
return stderr;
}
}
/*
* Copyright (c) 2013, 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.
*/
package com.oracle.java.testlibrary;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.lang.management.ManagementFactory;
import java.lang.management.RuntimeMXBean;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
import sun.management.VMManagement;
public final class ProcessTools {
private ProcessTools() {
}
/**
* Pumps stdout and stderr from running the process into a String.
*
* @param processHandler ProcessHandler to run.
* @return Output from process.
* @throws IOException If an I/O error occurs.
*/
public static OutputBuffer getOutput(ProcessBuilder processBuilder) throws IOException {
return getOutput(processBuilder.start());
}
/**
* Pumps stdout and stderr the running process into a String.
*
* @param process Process to pump.
* @return Output from process.
* @throws IOException If an I/O error occurs.
*/
public static OutputBuffer getOutput(Process process) throws IOException {
ByteArrayOutputStream stderrBuffer = new ByteArrayOutputStream();
ByteArrayOutputStream stdoutBuffer = new ByteArrayOutputStream();
StreamPumper outPumper = new StreamPumper(process.getInputStream(), stdoutBuffer);
StreamPumper errPumper = new StreamPumper(process.getErrorStream(), stderrBuffer);
Thread outPumperThread = new Thread(outPumper);
Thread errPumperThread = new Thread(errPumper);
outPumperThread.setDaemon(true);
errPumperThread.setDaemon(true);
outPumperThread.start();
errPumperThread.start();
try {
process.waitFor();
outPumperThread.join();
errPumperThread.join();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
return null;
}
return new OutputBuffer(stdoutBuffer.toString(), stderrBuffer.toString());
}
/**
* Get the process id of the current running Java process
*
* @return Process id
*/
public static int getProcessId() throws Exception {
// Get the current process id using a reflection hack
RuntimeMXBean runtime = ManagementFactory.getRuntimeMXBean();
Field jvm = runtime.getClass().getDeclaredField("jvm");
jvm.setAccessible(true);
VMManagement mgmt = (sun.management.VMManagement) jvm.get(runtime);
Method pid_method = mgmt.getClass().getDeclaredMethod("getProcessId");
pid_method.setAccessible(true);
int pid = (Integer) pid_method.invoke(mgmt);
return pid;
}
/**
* Get platform specific VM arguments (e.g. -d64 on 64bit Solaris)
*
* @return String[] with platform specific arguments, empty if there are none
*/
public static String[] getPlatformSpecificVMArgs() {
String osName = System.getProperty("os.name");
String dataModel = System.getProperty("sun.arch.data.model");
if (osName.equals("SunOS") && dataModel.equals("64")) {
return new String[] { "-d64" };
}
return new String[] {};
}
/**
* Create ProcessBuilder using the java launcher from the jdk to be tested and
* with any platform specific arguments prepended
*/
public static ProcessBuilder createJavaProcessBuilder(String... command) throws Exception {
String javapath = JDKToolFinder.getJDKTool("java");
ArrayList<String> args = new ArrayList<>();
args.add(javapath);
Collections.addAll(args, getPlatformSpecificVMArgs());
Collections.addAll(args, command);
return new ProcessBuilder(args.toArray(new String[args.size()]));
}
}
/*
* Copyright (c) 2013, 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.
*/
package com.oracle.java.testlibrary;
import java.io.OutputStream;
import java.io.InputStream;
import java.io.IOException;
public final class StreamPumper implements Runnable {
private static final int BUF_SIZE = 256;
private final OutputStream out;
private final InputStream in;
/**
* Create a StreamPumper that reads from in and writes to out.
*
* @param in The stream to read from.
* @param out The stream to write to.
*/
public StreamPumper(InputStream in, OutputStream out) {
this.in = in;
this.out = out;
}
/**
* Implements Thread.run(). Continuously read from <code>in</code> and write
* to <code>out</code> until <code>in</code> has reached end of stream. Abort
* on interruption. Abort on IOExceptions.
*/
@Override
public void run() {
int length;
InputStream localIn = in;
OutputStream localOut = out;
byte[] buffer = new byte[BUF_SIZE];
try {
while (!Thread.interrupted() && (length = localIn.read(buffer)) > 0) {
localOut.write(buffer, 0, length);
}
} catch (IOException e) {
// Just abort if something like this happens.
e.printStackTrace();
} finally {
try {
localOut.flush();
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册