8022229: Intermittent test failures in sun/tools/jstatd
authorykantser
Wed, 30 Oct 2013 13:44:40 +0100
changeset 21410 5f3e83a059c4
parent 21409 246ccfb4a0f0
child 21411 e3d8a6eaad27
8022229: Intermittent test failures in sun/tools/jstatd Reviewed-by: sla, egahlin, jbachorik, allwin
jdk/test/lib/testlibrary/jdk/testlibrary/Asserts.java
jdk/test/lib/testlibrary/jdk/testlibrary/JDKToolFinder.java
jdk/test/lib/testlibrary/jdk/testlibrary/JDKToolLauncher.java
jdk/test/lib/testlibrary/jdk/testlibrary/Platform.java
jdk/test/lib/testlibrary/jdk/testlibrary/ProcessThread.java
jdk/test/lib/testlibrary/jdk/testlibrary/TestThread.java
jdk/test/lib/testlibrary/jdk/testlibrary/Utils.java
jdk/test/lib/testlibrary/jdk/testlibrary/XRun.java
jdk/test/sun/tools/jstatd/JstatGCUtilParser.java
jdk/test/sun/tools/jstatd/JstatdTest.java
jdk/test/sun/tools/jstatd/TestJstatdDefaults.java
jdk/test/sun/tools/jstatd/TestJstatdExternalRegistry.java
jdk/test/sun/tools/jstatd/TestJstatdPort.java
jdk/test/sun/tools/jstatd/TestJstatdPortAndServer.java
jdk/test/sun/tools/jstatd/TestJstatdServer.java
jdk/test/sun/tools/jstatd/TestJstatdUsage.java
jdk/test/sun/tools/jstatd/jpsOutput1.awk
jdk/test/sun/tools/jstatd/jstatGcutilOutput1.awk
jdk/test/sun/tools/jstatd/jstatdDefaults.sh
jdk/test/sun/tools/jstatd/jstatdExternalRegistry.sh
jdk/test/sun/tools/jstatd/jstatdPort.sh
jdk/test/sun/tools/jstatd/jstatdServerName.sh
jdk/test/sun/tools/jstatd/jstatdUsage1.sh
jdk/test/sun/tools/jstatd/usage.out
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/lib/testlibrary/jdk/testlibrary/Asserts.java	Wed Oct 30 13:44:40 2013 +0100
@@ -0,0 +1,395 @@
+/*
+ * 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 jdk.testlibrary;
+
+/**
+ * Asserts that can be used for verifying assumptions in tests.
+ *
+ * An assertion will throw a {@link RuntimeException} if the assertion isn't
+ * valid.  All the asserts can be imported into a test by using a static
+ * import:
+ *
+ * <pre>
+ * {@code
+ * import static com.oracle.java.testlibrary.Asserts.*;
+ * }
+ *
+ * Always provide a message describing the assumption if the line number of the
+ * failing assertion isn't enough to understand why the assumption failed. For
+ * example, if the assertion is in a loop or in a method that is called
+ * multiple times, then the line number won't provide enough context to
+ * understand the failure.
+ * </pre>
+ */
+public class Asserts {
+
+    /**
+     * Shorthand for {@link #assertLessThan(T, T)}.
+     *
+     * @see #assertLessThan(T, T)
+     */
+    public static <T extends Comparable<T>> void assertLT(T lhs, T rhs) {
+        assertLessThan(lhs, rhs);
+    }
+
+    /**
+     * Shorthand for {@link #assertLessThan(T, T, String)}.
+     *
+     * @see #assertLessThan(T, T, String)
+     */
+    public static <T extends Comparable<T>> void assertLT(T lhs, T rhs, String msg) {
+        assertLessThan(lhs, rhs, msg);
+    }
+
+    /**
+     * Calls {@link #assertLessThan(T, T, String)} with a default message.
+     *
+     * @see #assertLessThan(T, T, String)
+     */
+    public static <T extends Comparable<T>> void assertLessThan(T lhs, T rhs) {
+        String msg = "Expected that " + format(lhs) + " < " + format(rhs);
+        assertLessThan(lhs, rhs, msg);
+    }
+
+    /**
+     * Asserts that {@code lhs} is less than {@code rhs}.
+     *
+     * @param lhs The left hand side of the comparison.
+     * @param rhs The right hand side of the comparison.
+     * @param msg A description of the assumption.
+     * @throws RuntimeException if the assertion isn't valid.
+     */
+    public static <T extends Comparable<T>>void assertLessThan(T lhs, T rhs, String msg) {
+        assertTrue(compare(lhs, rhs, msg) < 0, msg);
+    }
+
+    /**
+     * Shorthand for {@link #assertLessThanOrEqual(T, T)}.
+     *
+     * @see #assertLessThanOrEqual(T, T)
+     */
+    public static <T extends Comparable<T>> void assertLTE(T lhs, T rhs) {
+        assertLessThanOrEqual(lhs, rhs);
+    }
+
+    /**
+     * Shorthand for {@link #assertLessThanOrEqual(T, T, String)}.
+     *
+     * @see #assertLessThanOrEqual(T, T, String)
+     */
+    public static <T extends Comparable<T>> void assertLTE(T lhs, T rhs, String msg) {
+        assertLessThanOrEqual(lhs, rhs, msg);
+    }
+
+    /**
+     * Calls {@link #assertLessThanOrEqual(T, T, String)} with a default message.
+     *
+     * @see #assertLessThanOrEqual(T, T, String)
+     */
+    public static <T extends Comparable<T>> void assertLessThanOrEqual(T lhs, T rhs) {
+        String msg = "Expected that " + format(lhs) + " <= " + format(rhs);
+        assertLessThanOrEqual(lhs, rhs, msg);
+    }
+
+    /**
+     * Asserts that {@code lhs} is less than or equal to {@code rhs}.
+     *
+     * @param lhs The left hand side of the comparison.
+     * @param rhs The right hand side of the comparison.
+     * @param msg A description of the assumption.
+     * @throws RuntimeException if the assertion isn't valid.
+     */
+    public static <T extends Comparable<T>> void assertLessThanOrEqual(T lhs, T rhs, String msg) {
+        assertTrue(compare(lhs, rhs, msg) <= 0, msg);
+    }
+
+    /**
+     * Shorthand for {@link #assertEquals(T, T)}.
+     *
+     * @see #assertEquals(T, T)
+     */
+    public static void assertEQ(Object lhs, Object rhs) {
+        assertEquals(lhs, rhs);
+    }
+
+    /**
+     * Shorthand for {@link #assertEquals(T, T, String)}.
+     *
+     * @see #assertEquals(T, T, String)
+     */
+    public static void assertEQ(Object lhs, Object rhs, String msg) {
+        assertEquals(lhs, rhs, msg);
+    }
+
+    /**
+     * Calls {@link #assertEquals(T, T, String)} with a default message.
+     *
+     * @see #assertEquals(T, T, String)
+     */
+    public static void assertEquals(Object lhs, Object rhs) {
+        String msg = "Expected " + format(lhs) + " to equal " + format(rhs);
+        assertEquals(lhs, rhs, msg);
+    }
+
+    /**
+     * Asserts that {@code lhs} is equal to {@code rhs}.
+     *
+     * @param lhs The left hand side of the comparison.
+     * @param rhs The right hand side of the comparison.
+     * @param msg A description of the assumption.
+     * @throws RuntimeException if the assertion isn't valid.
+     */
+    public static void assertEquals(Object lhs, Object rhs, String msg) {
+        if (lhs == null) {
+            if (rhs != null) {
+                error(msg);
+            }
+        } else {
+            assertTrue(lhs.equals(rhs), msg);
+        }
+    }
+
+    /**
+     * Shorthand for {@link #assertGreaterThanOrEqual(T, T)}.
+     *
+     * @see #assertGreaterThanOrEqual(T, T)
+     */
+    public static <T extends Comparable<T>> void assertGTE(T lhs, T rhs) {
+        assertGreaterThanOrEqual(lhs, rhs);
+    }
+
+    /**
+     * Shorthand for {@link #assertGreaterThanOrEqual(T, T, String)}.
+     *
+     * @see #assertGreaterThanOrEqual(T, T, String)
+     */
+    public static <T extends Comparable<T>> void assertGTE(T lhs, T rhs, String msg) {
+        assertGreaterThanOrEqual(lhs, rhs, msg);
+    }
+
+    /**
+     * Calls {@link #assertGreaterThanOrEqual(T, T, String)} with a default message.
+     *
+     * @see #assertGreaterThanOrEqual(T, T, String)
+     */
+    public static <T extends Comparable<T>> void assertGreaterThanOrEqual(T lhs, T rhs) {
+        String msg = "Expected that " + format(lhs) + " >= " + format(rhs);
+        assertGreaterThanOrEqual(lhs, rhs, msg);
+    }
+
+    /**
+     * Asserts that {@code lhs} is greater than or equal to {@code rhs}.
+     *
+     * @param lhs The left hand side of the comparison.
+     * @param rhs The right hand side of the comparison.
+     * @param msg A description of the assumption.
+     * @throws RuntimeException if the assertion isn't valid.
+     */
+    public static <T extends Comparable<T>> void assertGreaterThanOrEqual(T lhs, T rhs, String msg) {
+        assertTrue(compare(lhs, rhs, msg) >= 0, msg);
+    }
+
+    /**
+     * Shorthand for {@link #assertGreaterThan(T, T)}.
+     *
+     * @see #assertGreaterThan(T, T)
+     */
+    public static <T extends Comparable<T>> void assertGT(T lhs, T rhs) {
+        assertGreaterThan(lhs, rhs);
+    }
+
+    /**
+     * Shorthand for {@link #assertGreaterThan(T, T, String)}.
+     *
+     * @see #assertGreaterThan(T, T, String)
+     */
+    public static <T extends Comparable<T>> void assertGT(T lhs, T rhs, String msg) {
+        assertGreaterThan(lhs, rhs, msg);
+    }
+
+    /**
+     * Calls {@link #assertGreaterThan(T, T, String)} with a default message.
+     *
+     * @see #assertGreaterThan(T, T, String)
+     */
+    public static <T extends Comparable<T>> void assertGreaterThan(T lhs, T rhs) {
+        String msg = "Expected that " + format(lhs) + " > " + format(rhs);
+        assertGreaterThan(lhs, rhs, msg);
+    }
+
+    /**
+     * Asserts that {@code lhs} is greater than {@code rhs}.
+     *
+     * @param lhs The left hand side of the comparison.
+     * @param rhs The right hand side of the comparison.
+     * @param msg A description of the assumption.
+     * @throws RuntimeException if the assertion isn't valid.
+     */
+    public static <T extends Comparable<T>> void assertGreaterThan(T lhs, T rhs, String msg) {
+        assertTrue(compare(lhs, rhs, msg) > 0, msg);
+    }
+
+    /**
+     * Shorthand for {@link #assertNotEquals(T, T)}.
+     *
+     * @see #assertNotEquals(T, T)
+     */
+    public static void assertNE(Object lhs, Object rhs) {
+        assertNotEquals(lhs, rhs);
+    }
+
+    /**
+     * Shorthand for {@link #assertNotEquals(T, T, String)}.
+     *
+     * @see #assertNotEquals(T, T, String)
+     */
+    public static void assertNE(Object lhs, Object rhs, String msg) {
+        assertNotEquals(lhs, rhs, msg);
+    }
+
+    /**
+     * Calls {@link #assertNotEquals(T, T, String)} with a default message.
+     *
+     * @see #assertNotEquals(T, T, String)
+     */
+    public static void assertNotEquals(Object lhs, Object rhs) {
+        String msg = "Expected " + format(lhs) + " to not equal " + format(rhs);
+        assertNotEquals(lhs, rhs, msg);
+    }
+
+    /**
+     * Asserts that {@code lhs} is not equal to {@code rhs}.
+     *
+     * @param lhs The left hand side of the comparison.
+     * @param rhs The right hand side of the comparison.
+     * @param msg A description of the assumption.
+     * @throws RuntimeException if the assertion isn't valid.
+     */
+    public static void assertNotEquals(Object lhs, Object rhs, String msg) {
+        if (lhs == null) {
+            if (rhs == null) {
+                error(msg);
+            }
+        } else {
+            assertFalse(lhs.equals(rhs), msg);
+        }
+    }
+
+    /**
+     * Calls {@link #assertNull(Object, String)} with a default message.
+     *
+     * @see #assertNull(Object, String)
+     */
+    public static void assertNull(Object o) {
+        assertNull(o, "Expected " + format(o) + " to be null");
+    }
+
+    /**
+     * Asserts that {@code o} is null.
+     *
+     * @param o The reference assumed to be null.
+     * @param msg A description of the assumption.
+     * @throws RuntimeException if the assertion isn't valid.
+     */
+    public static void assertNull(Object o, String msg) {
+        assertEquals(o, null, msg);
+    }
+
+    /**
+     * Calls {@link #assertNotNull(Object, String)} with a default message.
+     *
+     * @see #assertNotNull(Object, String)
+     */
+    public static void assertNotNull(Object o) {
+        assertNotNull(o, "Expected non null reference");
+    }
+
+    /**
+     * Asserts that {@code o} is <i>not</i> null.
+     *
+     * @param o The reference assumed <i>not</i> to be null,
+     * @param msg A description of the assumption.
+     * @throws RuntimeException if the assertion isn't valid.
+     */
+    public static void assertNotNull(Object o, String msg) {
+        assertNotEquals(o, null, msg);
+    }
+
+    /**
+     * Calls {@link #assertFalse(boolean, String)} with a default message.
+     *
+     * @see #assertFalse(boolean, String)
+     */
+    public static void assertFalse(boolean value) {
+        assertFalse(value, "Expected value to be false");
+    }
+
+    /**
+     * Asserts that {@code value} is {@code false}.
+     *
+     * @param value The value assumed to be false.
+     * @param msg A description of the assumption.
+     * @throws RuntimeException if the assertion isn't valid.
+     */
+    public static void assertFalse(boolean value, String msg) {
+        assertTrue(!value, msg);
+    }
+
+    /**
+     * Calls {@link #assertTrue(boolean, String)} with a default message.
+     *
+     * @see #assertTrue(boolean, String)
+     */
+    public static void assertTrue(boolean value) {
+        assertTrue(value, "Expected value to be true");
+    }
+
+    /**
+     * Asserts that {@code value} is {@code true}.
+     *
+     * @param value The value assumed to be true.
+     * @param msg A description of the assumption.
+     * @throws RuntimeException if the assertion isn't valid.
+     */
+    public static void assertTrue(boolean value, String msg) {
+        if (!value) {
+            error(msg);
+        }
+    }
+
+    private static <T extends Comparable<T>> int compare(T lhs, T rhs, String msg) {
+        assertNotNull(lhs, msg);
+        assertNotNull(rhs, msg);
+        return lhs.compareTo(rhs);
+    }
+
+    private static String format(Object o) {
+        return o == null? "null" : o.toString();
+    }
+
+    private static void error(String msg) {
+        throw new RuntimeException(msg);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/lib/testlibrary/jdk/testlibrary/JDKToolFinder.java	Wed Oct 30 13:44:40 2013 +0100
@@ -0,0 +1,106 @@
+/*
+ * 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 jdk.testlibrary;
+
+import java.io.FileNotFoundException;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+public final class JDKToolFinder {
+
+    private JDKToolFinder() {
+    }
+
+    /**
+     * Returns the full path to an executable in jdk/bin based on System
+     * property {@code test.jdk} or {@code compile.jdk} (both are set by the jtreg test suite)
+     *
+     * @return Full path to an executable in jdk/bin
+     */
+    public static String getJDKTool(String tool) {
+
+        // First try to find the executable in test.jdk
+        try {
+            return getTool(tool, "test.jdk");
+        } catch (FileNotFoundException e) {
+
+        }
+
+        // Now see if it's available in compile.jdk
+        try {
+            return getTool(tool, "compile.jdk");
+        } catch (FileNotFoundException e) {
+            throw new RuntimeException("Failed to find " + tool +
+                    ", looked in test.jdk (" + System.getProperty("test.jdk") +
+                    ") and compile.jdk (" + System.getProperty("compile.jdk") + ")");
+        }
+    }
+
+    /**
+     * Returns the full path to an executable in jdk/bin based on System
+     * property {@code compile.jdk}
+     *
+     * @return Full path to an executable in jdk/bin
+     */
+    public static String getCompileJDKTool(String tool) {
+        try {
+            return getTool(tool, "compile.jdk");
+        } catch (FileNotFoundException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    /**
+     * Returns the full path to an executable in jdk/bin based on System
+     * property {@code test.jdk}
+     *
+     * @return Full path to an executable in jdk/bin
+     */
+    public static String getTestJDKTool(String tool) {
+        try {
+            return getTool(tool, "test.jdk");
+        } catch (FileNotFoundException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    private static String getTool(String tool, String property) throws FileNotFoundException {
+        String jdkPath = System.getProperty(property);
+
+        if (jdkPath == null) {
+            throw new RuntimeException(
+                    "System property '" + property + "' not set. This property is normally set by jtreg. "
+                    + "When running test separately, set this property using '-D" + property + "=/path/to/jdk'.");
+        }
+
+        Path toolName = Paths.get("bin", tool + (Platform.isWindows() ? ".exe" : ""));
+
+        Path jdkTool = Paths.get(jdkPath, toolName.toString());
+        if (!jdkTool.toFile().exists()) {
+            throw new FileNotFoundException("Could not find file " + jdkTool.toAbsolutePath());
+        }
+
+        return jdkTool.toAbsolutePath().toString();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/lib/testlibrary/jdk/testlibrary/JDKToolLauncher.java	Wed Oct 30 13:44:40 2013 +0100
@@ -0,0 +1,134 @@
+/*
+ * 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 jdk.testlibrary;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * A utility for constructing command lines for starting JDK tool processes.
+ *
+ * The JDKToolLauncher can in particular be combined with a
+ * java.lang.ProcessBuilder to easily run a JDK tool. For example, the following
+ * code run {@code jmap -heap} against a process with GC logging turned on for
+ * the {@code jmap} process:
+ *
+ * <pre>
+ * {@code
+ * JDKToolLauncher jmap = JDKToolLauncher.create("jmap")
+ *                                       .addVMArg("-XX:+PrintGC");
+ *                                       .addVMArg("-XX:+PrintGCDetails")
+ *                                       .addToolArg("-heap")
+ *                                       .addToolArg(pid);
+ * ProcessBuilder pb = new ProcessBuilder(jmap.getCommand());
+ * Process p = pb.start();
+ * }
+ * </pre>
+ */
+public class JDKToolLauncher {
+    private final String executable;
+    private final List<String> vmArgs = new ArrayList<String>();
+    private final List<String> toolArgs = new ArrayList<String>();
+
+    private JDKToolLauncher(String tool, boolean useCompilerJDK) {
+        if (useCompilerJDK) {
+            executable = JDKToolFinder.getJDKTool(tool);
+        } else {
+            executable = JDKToolFinder.getTestJDKTool(tool);
+        }
+        vmArgs.addAll(Arrays.asList(ProcessTools.getPlatformSpecificVMArgs()));
+    }
+
+    /**
+     * Creates a new JDKToolLauncher for the specified tool. Using tools path
+     * from the compiler JDK.
+     *
+     * @param tool
+     *            The name of the tool
+     * @return A new JDKToolLauncher
+     */
+    public static JDKToolLauncher create(String tool) {
+        return new JDKToolLauncher(tool, true);
+    }
+
+    /**
+     * Creates a new JDKToolLauncher for the specified tool in the Tested JDK.
+     *
+     * @param tool
+     *            The name of the tool
+     *
+     * @return A new JDKToolLauncher
+     */
+    public static JDKToolLauncher createUsingTestJDK(String tool) {
+        return new JDKToolLauncher(tool, false);
+    }
+
+    /**
+     * Adds an argument to the JVM running the tool.
+     *
+     * The JVM arguments are passed to the underlying JVM running the tool.
+     * Arguments will automatically be prepended with "-J".
+     *
+     * Any platform specific arguments required for running the tool are
+     * automatically added.
+     *
+     *
+     * @param arg
+     *            The argument to VM running the tool
+     * @return The JDKToolLauncher instance
+     */
+    public JDKToolLauncher addVMArg(String arg) {
+        vmArgs.add(arg);
+        return this;
+    }
+
+    /**
+     * Adds an argument to the tool.
+     *
+     * @param arg
+     *            The argument to the tool
+     * @return The JDKToolLauncher instance
+     */
+    public JDKToolLauncher addToolArg(String arg) {
+        toolArgs.add(arg);
+        return this;
+    }
+
+    /**
+     * Returns the command that can be used for running the tool.
+     *
+     * @return An array whose elements are the arguments of the command.
+     */
+    public String[] getCommand() {
+        List<String> command = new ArrayList<String>();
+        command.add(executable);
+        // Add -J in front of all vmArgs
+        for (String arg : vmArgs) {
+            command.add("-J" + arg);
+        }
+        command.addAll(toolArgs);
+        return command.toArray(new String[command.size()]);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/lib/testlibrary/jdk/testlibrary/Platform.java	Wed Oct 30 13:44:40 2013 +0100
@@ -0,0 +1,103 @@
+/*
+ * 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 jdk.testlibrary;
+
+public class Platform {
+    private static final String osName      = System.getProperty("os.name");
+    private static final String dataModel   = System.getProperty("sun.arch.data.model");
+    private static final String vmVersion   = System.getProperty("java.vm.version");
+    private static final String osArch      = System.getProperty("os.arch");
+
+    public static boolean is32bit() {
+        return dataModel.equals("32");
+    }
+
+    public static boolean is64bit() {
+        return dataModel.equals("64");
+    }
+
+    public static boolean isSolaris() {
+        return isOs("sunos");
+    }
+
+    public static boolean isWindows() {
+        return isOs("win");
+    }
+
+    public static boolean isOSX() {
+        return isOs("mac");
+    }
+
+    public static boolean isLinux() {
+        return isOs("linux");
+    }
+
+    private static boolean isOs(String osname) {
+        return osName.toLowerCase().startsWith(osname.toLowerCase());
+    }
+
+    public static String getOsName() {
+        return osName;
+    }
+
+    public static boolean isDebugBuild() {
+        return vmVersion.toLowerCase().contains("debug");
+    }
+
+    public static String getVMVersion() {
+        return vmVersion;
+    }
+
+    // Returns true for sparc and sparcv9.
+    public static boolean isSparc() {
+        return isArch("sparc");
+    }
+
+    public static boolean isARM() {
+        return isArch("arm");
+    }
+
+    public static boolean isPPC() {
+        return isArch("ppc");
+    }
+
+    public static boolean isX86() {
+        // On Linux it's 'i386', Windows 'x86'
+        return (isArch("i386") || isArch("x86"));
+    }
+
+    public static boolean isX64() {
+        // On OSX it's 'x86_64' and on other (Linux, Windows and Solaris) platforms it's 'amd64'
+        return (isArch("amd64") || isArch("x86_64"));
+    }
+
+    private static boolean isArch(String archname) {
+        return osArch.toLowerCase().startsWith(archname.toLowerCase());
+    }
+
+    public static String getOsArch() {
+        return osArch;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/lib/testlibrary/jdk/testlibrary/ProcessThread.java	Wed Oct 30 13:44:40 2013 +0100
@@ -0,0 +1,151 @@
+/*
+ * 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 jdk.testlibrary;
+
+import static jdk.testlibrary.Asserts.assertNotEquals;
+import static jdk.testlibrary.Asserts.assertTrue;
+
+import java.util.List;
+import java.util.concurrent.CountDownLatch;
+
+/**
+ * The helper class for starting and stopping {@link Process} in a separate thread.
+ */
+public class ProcessThread extends TestThread {
+
+    /**
+     * Creates a new {@code ProcessThread} object.
+     *
+     * @param cmd The list of program and its arguments to pass to {@link ProcessBuilder}
+     */
+    public ProcessThread(List<String> cmd) {
+        super(new ProcessRunnable(cmd));
+    }
+
+    /**
+     * Creates a new {@code ProcessThread} object.
+     *
+     * @param cmd The string array of program and its arguments to pass to {@link ProcessBuilder}
+     */
+    public ProcessThread(String... cmd) {
+        super(new ProcessRunnable(cmd));
+    }
+
+    /**
+     * Creates a new {@code ProcessThread} object.
+     *
+     * @param threadName The name of thread
+     * @param cmd The list of program and its arguments to pass to {@link ProcessBuilder}
+     */
+    public ProcessThread(String threadName, List<String> cmd) {
+        super(new ProcessRunnable(cmd), threadName);
+    }
+
+    /**
+     * Creates a new {@code ProcessThread} object.
+     *
+     * @param threadName The name of thread
+     * @param cmd The string array of program and its arguments to pass to {@link ProcessBuilder}
+     */
+    public ProcessThread(String threadName, String... cmd) {
+        super(new ProcessRunnable(cmd), threadName);
+    }
+
+    /**
+     * Stops {@link Process} started by {@code ProcessRunnable}.
+     *
+     * @throws InterruptedException
+     */
+    public void stopProcess() throws InterruptedException {
+        ((ProcessRunnable) getRunnable()).stopProcess();
+    }
+
+    /**
+     * {@link Runnable} interface for starting and stopping {@link Process}.
+     */
+    static class ProcessRunnable extends XRun {
+
+        private final ProcessBuilder processBuilder;
+        private final CountDownLatch latch;
+        private volatile Process process;
+
+        /**
+         * Creates a new {@code ProcessRunnable} object.
+         *
+         * @param cmd The list of program and its arguments to to pass to {@link ProcessBuilder}
+         */
+        public ProcessRunnable(List<String> cmd) {
+            super();
+            this.processBuilder = new ProcessBuilder(cmd);
+            this.latch = new CountDownLatch(1);
+        }
+
+        /**
+         * Creates a new {@code ProcessRunnable} object.
+         *
+         * @param cmd The string array of program and its arguments to to pass to {@link ProcessBuilder}
+         */
+        public ProcessRunnable(String... cmd) {
+            super();
+            this.processBuilder = new ProcessBuilder(cmd);
+            this.latch = new CountDownLatch(1);
+        }
+
+        /**
+         * Starts the process in {@code ProcessThread}.
+         * All exceptions which occurs here will be caught and stored in {@code ProcessThread}.
+         *
+         * see {@link XRun}
+         */
+        @Override
+        public void xrun() throws Throwable {
+            this.process = processBuilder.start();
+            // Release when process is started
+            latch.countDown();
+
+            // Will block...
+            OutputAnalyzer output = new OutputAnalyzer(this.process);
+
+            assertTrue(output.getOutput().isEmpty(), "Should get an empty output, got: "
+                        + Utils.NEW_LINE + output.getOutput());
+            assertNotEquals(output.getExitValue(), 0,
+                    "Process exited with unexpected exit code");
+        }
+
+        /**
+         * Stops the process.
+         *
+         * @throws InterruptedException
+         */
+        public void stopProcess() throws InterruptedException {
+            // Wait until process is started
+            latch.await();
+            if (this.process != null) {
+                this.process.destroy();
+            }
+        }
+
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/lib/testlibrary/jdk/testlibrary/TestThread.java	Wed Oct 30 13:44:40 2013 +0100
@@ -0,0 +1,249 @@
+/*
+ * 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 jdk.testlibrary;
+
+import java.lang.management.ManagementFactory;
+import java.lang.management.ThreadInfo;
+import java.lang.management.ThreadMXBean;
+import java.util.concurrent.TimeoutException;
+
+/**
+ * Thread which catches exceptions thrown during the execution
+ * and stores them for later analysis.
+ *
+ * <pre>
+ * {@code
+ * TestThread thread = new TestThread(new XRun() {
+ *      public void run() {
+ *      // do something
+ *      }
+ * });
+ * thread.start();
+ * // do something
+ * Throwable uncaught = thread.getUncaught();
+ * }
+ * </pre>
+ */
+public class TestThread extends Thread {
+
+    private final Runnable runnable;
+    private volatile Throwable uncaught;
+
+    /**
+     * Returns {@link Runnable} the thread has been created with.
+     *
+     * @return The object whose {@code run} method is called
+     */
+    public Runnable getRunnable() {
+        return runnable;
+    }
+
+    /**
+     * Creates a new {@code TestThread} object.
+     *
+     * @param target The object whose {@code run} method is called
+     * @param name The thread name
+     */
+    public TestThread(Runnable target, String name) {
+        super(target, name);
+        this.runnable = target;
+    }
+
+    /**
+     * Creates a new {@code TestThread} object.
+     *
+     * @param target The object whose {@code run} method is called
+     */
+    public TestThread(Runnable target) {
+        super(target);
+        this.runnable = target;
+    }
+
+    /**
+     * Creates a new {@code TestThread} object.
+     *
+     * @param group The thread group
+     * @param target The object whose {@code run} method is called
+     * @param name The thread name
+     * @param stackSize Stack size
+     */
+    public TestThread(ThreadGroup group, Runnable target, String name,
+            long stackSize) {
+        super(group, target, name, stackSize);
+        this.runnable = target;
+    }
+
+    /**
+     * Creates a new {@code TestThread} object.
+     *
+     * @param group The thread group
+     * @param target The object whose {@code run} method is called
+     * @param name The thread name
+     */
+    public TestThread(ThreadGroup group, Runnable target, String name) {
+        super(group, target, name);
+        this.runnable = target;
+    }
+
+    /**
+     * Creates a new {@code TestThread} object.
+     *
+     * @param group The thread group
+     * @param target The object whose {@code run} method is called
+     */
+    public TestThread(ThreadGroup group, Runnable target) {
+        super(group, target);
+        this.runnable = target;
+    }
+
+    /**
+     * The thread executor.
+     */
+    @Override
+    public void run() {
+        try {
+            super.run();
+        } catch (Throwable t) {
+            uncaught = t;
+        }
+    }
+
+    /**
+     * Returns exception caught during the execution.
+     *
+     * @return {@link Throwable}
+     */
+    public Throwable getUncaught() {
+        return uncaught;
+    }
+
+    /**
+     * Waits for {@link TestThread} to die
+     * and throws exception caught during the execution.
+     *
+     * @throws InterruptedException
+     * @throws Throwable
+     */
+    public void joinAndThrow() throws InterruptedException, Throwable {
+        join();
+        if (uncaught != null) {
+            throw uncaught;
+        }
+    }
+
+    /**
+     * Waits during {@code timeout} for {@link TestThread} to die
+     * and throws exception caught during the execution.
+     *
+     * @param timeout The time to wait in milliseconds
+     * @throws InterruptedException
+     * @throws Throwable
+     */
+    public void joinAndThrow(long timeout) throws InterruptedException,
+            Throwable {
+        join(timeout);
+        if (isAlive()) {
+            throw new TimeoutException();
+        }
+        if (uncaught != null) {
+            throw uncaught;
+        }
+    }
+
+    /**
+     * Waits for {@link TestThread} to die
+     * and returns exception caught during the execution.
+     *
+     * @return Exception caught during the execution
+     * @throws InterruptedException
+     */
+    public Throwable joinAndReturn() throws InterruptedException {
+        join();
+        if (uncaught != null) {
+            return uncaught;
+        }
+        return null;
+    }
+
+    /**
+     * Waits during {@code timeout} for {@link TestThread} to die
+     * and returns exception caught during the execution.
+     *
+     * @param timeout The time to wait in milliseconds
+     * @return Exception caught during the execution
+     * @throws InterruptedException
+     */
+    public Throwable joinAndReturn(long timeout) throws InterruptedException {
+        join(timeout);
+        if (isAlive()) {
+            return new TimeoutException();
+        }
+        if (uncaught != null) {
+            return uncaught;
+        }
+        return null;
+    }
+
+    /**
+     * Waits until {@link TestThread} is in the certain {@link State}
+     * and blocking on {@code object}.
+     *
+     * @param state The thread state
+     * @param object The object to block on
+     */
+    public void waitUntilBlockingOnObject(Thread.State state, Object object) {
+        String want = object == null ? null : object.getClass().getName() + '@'
+                + Integer.toHexString(System.identityHashCode(object));
+        ThreadMXBean tmx = ManagementFactory.getThreadMXBean();
+        while (isAlive()) {
+            ThreadInfo ti = tmx.getThreadInfo(getId());
+            if (ti.getThreadState() == state
+                    && (want == null || want.equals(ti.getLockName()))) {
+                return;
+            }
+            try {
+                Thread.sleep(1);
+            } catch (InterruptedException e) {
+            }
+        }
+    }
+
+    /**
+     * Waits until {@link TestThread} is in native.
+     */
+    public void waitUntilInNative() {
+        ThreadMXBean tmx = ManagementFactory.getThreadMXBean();
+        while (isAlive()) {
+            ThreadInfo ti = tmx.getThreadInfo(getId());
+            if (ti.isInNative()) {
+                return;
+            }
+            try {
+                Thread.sleep(1);
+            } catch (InterruptedException e) {
+            }
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/lib/testlibrary/jdk/testlibrary/Utils.java	Wed Oct 30 13:44:40 2013 +0100
@@ -0,0 +1,132 @@
+/*
+ * 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 jdk.testlibrary;
+
+import static jdk.testlibrary.Asserts.assertTrue;
+
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.ServerSocket;
+import java.net.UnknownHostException;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Common library for various test helper functions.
+ */
+public final class Utils {
+
+    /**
+     * Returns the sequence used by operating system to separate lines.
+     */
+    public static final String NEW_LINE = System.getProperty("line.separator");
+
+    /**
+     * Returns the value of 'test.vm.opts'system property.
+     */
+    public static final String VM_OPTIONS = System.getProperty("test.vm.opts", "");
+
+
+    private Utils() {
+        // Private constructor to prevent class instantiation
+    }
+
+    /**
+     * Returns the list of VM options.
+     *
+     * @return List of VM options
+     */
+    public static List<String> getVmOptions() {
+        return getVmOptions(false);
+    }
+
+    /**
+     * Returns the list of VM options with -J prefix.
+     *
+     * @return The list of VM options with -J prefix
+     */
+    public static List<String> getForwardVmOptions() {
+        return getVmOptions(true);
+    }
+
+    private static List<String> getVmOptions(boolean forward) {
+        List<String> optionsList = new ArrayList<>();
+        String options = VM_OPTIONS.trim();
+        if (!options.isEmpty()) {
+            options = options.replaceAll("\\s+", " ");
+            for (String option : options.split(" ")) {
+                if (forward) {
+                    optionsList.add("-J" + option);
+                } else {
+                    optionsList.add(option);
+                }
+            }
+        }
+
+        return optionsList;
+    }
+
+    /**
+     * Returns the free port on the local host.
+     * The function will spin until a valid port number is found.
+     *
+     * @return The port number
+     * @throws InterruptedException if any thread has interrupted the current thread
+     * @throws IOException if an I/O error occurs when opening the socket
+     */
+    public static int getFreePort() throws InterruptedException, IOException {
+        int port = -1;
+
+        while (port <= 0) {
+            Thread.sleep(100);
+
+            ServerSocket serverSocket = null;
+            try {
+                serverSocket = new ServerSocket(0);
+                port = serverSocket.getLocalPort();
+            } finally {
+                serverSocket.close();
+            }
+        }
+
+        return port;
+    }
+
+    /**
+     * Returns the name of the local host.
+     *
+     * @return The host name
+     * @throws UnknownHostException if IP address of a host could not be determined
+     */
+    public static String getHostname() throws UnknownHostException {
+        InetAddress inetAddress = InetAddress.getLocalHost();
+        String hostName = inetAddress.getHostName();
+
+        assertTrue((hostName != null && !hostName.isEmpty()),
+                "Cannot get hostname");
+
+        return hostName;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/lib/testlibrary/jdk/testlibrary/XRun.java	Wed Oct 30 13:44:40 2013 +0100
@@ -0,0 +1,56 @@
+/*
+ * 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 jdk.testlibrary;
+
+/**
+ * This type serves no other purpose than to simply allow automatically running
+ * something in a thread, and have all exceptions propagated to
+ * RuntimeExceptions, which are thrown up to thread, which in turn should
+ * probably be a {@link TestThread} to they are stored.
+ */
+public abstract class XRun implements Runnable {
+
+    /**
+     * Invokes {@code xrun()} and throws all exceptions caught in it
+     * up to the thread.
+     */
+    public final void run() {
+        try {
+            xrun();
+        } catch (Error e) {
+            throw e;
+        } catch (RuntimeException e) {
+            throw e;
+        } catch (Throwable e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    /**
+     * Override this method to implement what to run in the thread.
+     *
+     * @throws Throwable
+     */
+    protected abstract void xrun() throws Throwable;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/tools/jstatd/JstatGCUtilParser.java	Wed Oct 30 13:44:40 2013 +0100
@@ -0,0 +1,156 @@
+/*
+ * 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.
+ */
+
+import java.util.Arrays;
+
+import jdk.testlibrary.Utils;
+import static jdk.testlibrary.Asserts.*;
+
+/**
+ * The helper class for parsing following output from command 'jstat -gcutil':
+ *
+ *  S0     S1     E      O      M     CCS    YGC     YGCT    FGC    FGCT     GCT
+ *  100.00   0.00  64.68  13.17  73.39  33.46      2    0.003     1    0.156    0.158
+ *  100.00   0.00  76.54  13.17  73.39  33.46      2    0.003     1    0.156    0.158
+ *  100.00   0.00  83.49  13.17  73.39  33.46      2    0.003     1    0.156    0.158
+ *  100.00   0.00  84.53  13.17  73.39  33.46      2    0.003     1    0.156    0.158
+ *  100.00   0.00  85.57  13.17  73.39  33.46      2    0.003     1    0.156    0.158
+ *
+ *  It will be verified that numerical values have defined types and are reasonable,
+ *  for example percentage should fit within 0-100 interval.
+ */
+public class JstatGCUtilParser {
+
+    public enum GcStatisticsType {
+        INTEGER, DOUBLE, PERCENTAGE, PERCENTAGE_OR_DASH;
+    }
+
+    public enum GcStatistics {
+        S0(GcStatisticsType.PERCENTAGE),
+        S1(GcStatisticsType.PERCENTAGE),
+        E(GcStatisticsType.PERCENTAGE),
+        O(GcStatisticsType.PERCENTAGE),
+        M(GcStatisticsType.PERCENTAGE),
+        CCS(GcStatisticsType.PERCENTAGE_OR_DASH),
+        YGC(GcStatisticsType.INTEGER),
+        YGCT(GcStatisticsType.DOUBLE),
+        FGC(GcStatisticsType.INTEGER),
+        FGCT(GcStatisticsType.DOUBLE),
+        GCT(GcStatisticsType.DOUBLE);
+
+        private final GcStatisticsType type;
+
+        private GcStatistics(GcStatisticsType type) {
+            this.type = type;
+        }
+
+        private GcStatisticsType getType() {
+            return type;
+        }
+
+        public static boolean isHeadline(String... valueArray) {
+            if (valueArray.length != values().length) {
+                return false;
+            }
+            int headersCount = 0;
+            for (int i = 0; i < values().length; i++) {
+                if (valueArray[i].equals(values()[i].toString())) {
+                    headersCount++;
+                }
+            }
+            if (headersCount != values().length) {
+                return false;
+            }
+            return true;
+        }
+
+        private static void verifyLength(String... valueArray) throws Exception {
+            assertEquals(valueArray.length, values().length,
+                    "Invalid number of data columns: " + Arrays.toString(valueArray));
+        }
+
+        public static void verify(String... valueArray) throws Exception {
+            verifyLength(valueArray);
+            for (int i = 0; i < values().length; i++) {
+                GcStatisticsType type = values()[i].getType();
+                String value = valueArray[i].trim();
+                if (type.equals(GcStatisticsType.INTEGER)) {
+                    Integer.parseInt(value);
+                    break;
+                }
+                if (type.equals(GcStatisticsType.DOUBLE)) {
+                    Double.parseDouble(value);
+                    break;
+                }
+                if (type.equals(GcStatisticsType.PERCENTAGE_OR_DASH) &&
+                        value.equals("-")) {
+                    break;
+                }
+                double percentage = Double.parseDouble(value);
+                assertTrue(0 <= percentage && percentage <= 100,
+                        "Not a percentage: " + value);
+            }
+        }
+
+    }
+
+    private final String output;
+
+    public JstatGCUtilParser(String output) {
+        this.output = output;
+    }
+
+    public String getOutput() {
+        return output;
+    }
+
+    /**
+     * The function will discard any lines that come before the header line.
+     * This can happen if the JVM outputs a warning message for some reason
+     * before running jstat.
+     */
+    public void parse(int samples) throws Exception {
+        boolean headlineFound = false;
+        int datalineCount = 0;
+
+        String[] lines = output.split(Utils.NEW_LINE);
+        for (String line : lines) {
+            line = line.replaceAll("\\s+", " ").trim();
+            String[] valueArray = line.split(" ");
+
+            if (!headlineFound) {
+                headlineFound = GcStatistics.isHeadline(valueArray);
+                continue;
+            }
+
+            GcStatistics.verify(valueArray);
+            datalineCount++;
+        }
+
+        assertTrue(headlineFound, "No or invalid headline found, expected: " +
+                Utils.NEW_LINE + Arrays.toString(GcStatistics.values()).replaceAll(",", " "));
+        assertEquals(samples, datalineCount,
+                "Expected " + samples + " samples, got " + datalineCount);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/tools/jstatd/JstatdTest.java	Wed Oct 30 13:44:40 2013 +0100
@@ -0,0 +1,356 @@
+/*
+ * 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.
+ */
+
+import java.io.File;
+import java.net.UnknownHostException;
+import java.rmi.RemoteException;
+import java.rmi.registry.LocateRegistry;
+import java.rmi.registry.Registry;
+import java.util.Arrays;
+
+import static jdk.testlibrary.Asserts.*;
+import jdk.testlibrary.JDKToolLauncher;
+import jdk.testlibrary.OutputAnalyzer;
+import jdk.testlibrary.ProcessThread;
+import jdk.testlibrary.TestThread;
+import jdk.testlibrary.Utils;
+
+/**
+ * The base class for tests of jstatd.
+ *
+ * The test sequence for TestJstatdDefaults for example is:
+ * <pre>
+ * {@code
+ * // start jstatd process
+ * jstatd -J-XX:+UsePerfData -J-Djava.security.policy=all.policy
+ *
+ * // run jps and verify its output
+ * jps -J-XX:+UsePerfData hostname
+ *
+ * // run jstat and verify its output
+ * jstat -J-XX:+UsePerfData -J-Duser.language=en -gcutil pid@hostname 250 5
+ *
+ * // stop jstatd process and verify that no unexpected exceptions have been thrown
+ * }
+ * </pre>
+ */
+public final class JstatdTest {
+
+    /**
+     * jstat gcutil option: takes JSTAT_GCUTIL_SAMPLES samples at
+     * JSTAT_GCUTIL_INTERVAL_MS millisecond intervals
+     */
+    private static final int JSTAT_GCUTIL_SAMPLES = 5;
+    private static final int JSTAT_GCUTIL_INTERVAL_MS = 250;
+    private static final String JPS_OUTPUT_REGEX = "^\\d+\\s*.*";
+
+    private boolean useDefaultPort = true;
+    private String port;
+    private String serverName;
+    private String jstatdPid;
+    private boolean withExternalRegistry = false;
+
+    public void setServerName(String serverName) {
+        this.serverName = serverName;
+    }
+
+    public void setUseDefaultPort(boolean useDefaultPort) {
+        this.useDefaultPort = useDefaultPort;
+    }
+
+    public void setWithExternalRegistry(boolean withExternalRegistry) {
+        this.withExternalRegistry = withExternalRegistry;
+    }
+
+    /**
+     * Parse pid from jps output
+     */
+    private String parsePid(String tool, OutputAnalyzer output) throws Exception {
+        String[] lines = output.getOutput().split(Utils.NEW_LINE);
+        String pid = null;
+        int count = 0;
+        String processName = tool;
+        if (tool == "rmiregistry") {
+            processName = "registryimpl";
+        }
+        for (String line : lines) {
+            if (line.toLowerCase().matches("^\\d+\\s{1}" + processName + "$")) {
+                pid = line.split(" ")[0];
+                count++;
+            }
+        }
+        if (count > 1) {
+            throw new Exception("Expected one " + tool
+                    + " process, got " + count + ". Test will be canceled.");
+        }
+
+        return pid;
+    }
+
+    private String getToolPid(String tool)
+            throws Exception {
+        OutputAnalyzer output = runJps();
+        return parsePid(tool, output);
+    }
+
+    private String waitOnTool(String tool, TestThread thread) throws Throwable {
+        while (true) {
+            String pid = getToolPid(tool);
+
+            if (pid != null) {
+                System.out.println(tool + " pid: " + pid);
+                return pid;
+            }
+
+            Throwable t = thread.getUncaught();
+            if (t != null) {
+                if (t.getMessage().contains(
+                        "java.rmi.server.ExportException: Port already in use")) {
+                    System.out.println("Port already in use. Trying to restart with a new one...");
+                    Thread.sleep(100);
+                    return null;
+                } else {
+                    // Something unexpected has happened
+                    throw new Throwable(t);
+                }
+            }
+
+            System.out.println("Waiting until " + tool + " is running...");
+            Thread.sleep(100);
+        }
+    }
+
+    private void log(String caption, String... cmd) {
+        System.out.println(Utils.NEW_LINE + caption + ":");
+        System.out.println(Arrays.toString(cmd).replace(",", ""));
+    }
+
+    private String getDestination() throws UnknownHostException {
+        String option = Utils.getHostname();
+        if (port != null) {
+            option += ":" + port;
+        }
+        if (serverName != null) {
+            option += "/" + serverName;
+        }
+        return option;
+    }
+
+    /**
+     * Depending on test settings command line can look like:
+     *
+     * jps -J-XX:+UsePerfData hostname
+     * jps -J-XX:+UsePerfData hostname:port
+     * jps -J-XX:+UsePerfData hostname/serverName
+     * jps -J-XX:+UsePerfData hostname:port/serverName
+     */
+    private OutputAnalyzer runJps() throws Exception {
+        JDKToolLauncher launcher = JDKToolLauncher.createUsingTestJDK("jps");
+        launcher.addVMArg("-XX:+UsePerfData");
+        launcher.addToolArg(getDestination());
+
+        String[] cmd = launcher.getCommand();
+        log("Start jps", cmd);
+
+        ProcessBuilder processBuilder = new ProcessBuilder(cmd);
+        OutputAnalyzer output = new OutputAnalyzer(processBuilder.start());
+        System.out.println(output.getOutput());
+
+        return output;
+    }
+
+    /**
+     * Verifies output form jps contains pids and programs' name information.
+     * The function will discard any lines that come before the first line with pid.
+     * This can happen if the JVM outputs a warning message for some reason
+     * before running jps.
+     *
+     * The output can look like:
+     * 35536 Jstatd
+     * 35417 Main
+     * 31103 org.eclipse.equinox.launcher_1.3.0.v20120522-1813.jar
+     */
+    private void verifyJpsOutput(OutputAnalyzer output) throws Exception {
+        output.shouldHaveExitValue(0);
+        assertFalse(output.getOutput().isEmpty(), "Output should not be empty");
+
+        boolean foundFirstLineWithPid = false;
+        String[] lines = output.getOutput().split(Utils.NEW_LINE);
+        for (String line : lines) {
+            if (!foundFirstLineWithPid) {
+                foundFirstLineWithPid = line.matches(JPS_OUTPUT_REGEX);
+                continue;
+            }
+            assertTrue(line.matches(JPS_OUTPUT_REGEX),
+                    "Output does not match the pattern" + Utils.NEW_LINE + line);
+        }
+        assertTrue(foundFirstLineWithPid, "Invalid output");
+    }
+
+    /**
+     * Depending on test settings command line can look like:
+     *
+     * jstat -J-XX:+UsePerfData -J-Duser.language=en -gcutil pid@hostname 250 5
+     * jstat -J-XX:+UsePerfData -J-Duser.language=en -gcutil pid@hostname:port 250 5
+     * jstat -J-XX:+UsePerfData -J-Duser.language=en -gcutil pid@hostname/serverName 250 5
+     * jstat -J-XX:+UsePerfData -J-Duser.language=en -gcutil pid@hostname:port/serverName 250 5
+     */
+    private OutputAnalyzer runJstat() throws Exception {
+        JDKToolLauncher launcher = JDKToolLauncher.createUsingTestJDK("jstat");
+        launcher.addVMArg("-XX:+UsePerfData");
+        launcher.addVMArg("-Duser.language=en");
+        launcher.addToolArg("-gcutil");
+        launcher.addToolArg(jstatdPid + "@" + getDestination());
+        launcher.addToolArg(Integer.toString(JSTAT_GCUTIL_INTERVAL_MS));
+        launcher.addToolArg(Integer.toString(JSTAT_GCUTIL_SAMPLES));
+
+        String[] cmd = launcher.getCommand();
+        log("Start jstat", cmd);
+
+        ProcessBuilder processBuilder = new ProcessBuilder(cmd);
+        OutputAnalyzer output = new OutputAnalyzer(processBuilder.start());
+        System.out.println(output.getOutput());
+
+        return output;
+    }
+
+    private void verifyJstatOutput(OutputAnalyzer output)
+            throws Exception {
+        output.shouldHaveExitValue(0);
+        assertFalse(output.getOutput().isEmpty(), "Output should not be empty");
+
+        JstatGCUtilParser gcUtilParser = new JstatGCUtilParser(
+                output.getOutput());
+        gcUtilParser.parse(JSTAT_GCUTIL_SAMPLES);
+    }
+
+    private void runToolsAndVerify() throws Exception {
+        OutputAnalyzer output = runJps();
+        verifyJpsOutput(output);
+
+        output = runJstat();
+        verifyJstatOutput(output);
+    }
+
+    private Registry startRegistry()
+            throws InterruptedException, RemoteException {
+        Registry registry = null;
+        try {
+            System.out.println("Start rmiregistry on port " + port);
+            registry = LocateRegistry
+                    .createRegistry(Integer.parseInt(port));
+        } catch (RemoteException e) {
+            if (e.getMessage().contains("Port already in use")) {
+                System.out.println("Port already in use. Trying to restart with a new one...");
+                Thread.sleep(100);
+                return null;
+            } else {
+                throw e;
+            }
+        }
+        return registry;
+    }
+
+    private void cleanUpThread(ProcessThread thread) throws Throwable {
+        if (thread != null) {
+            thread.stopProcess();
+            thread.joinAndThrow();
+        }
+    }
+
+    /**
+     * Depending on test settings command line can look like:
+     *
+     * jstatd -J-XX:+UsePerfData -J-Djava.security.policy=all.policy
+     * jstatd -J-XX:+UsePerfData -J-Djava.security.policy=all.policy -p port
+     * jstatd -J-XX:+UsePerfData -J-Djava.security.policy=all.policy -n serverName
+     * jstatd -J-XX:+UsePerfData -J-Djava.security.policy=all.policy -p port -n serverName
+     */
+    private String[] getJstatdCmd() throws UnknownHostException {
+        JDKToolLauncher launcher = JDKToolLauncher.createUsingTestJDK("jstatd");
+        launcher.addVMArg("-XX:+UsePerfData");
+        String testSrc = System.getProperty("test.src");
+        File policy = new File(testSrc, "all.policy");
+        launcher.addVMArg("-Djava.security.policy=" + policy.getAbsolutePath());
+        if (port != null) {
+            launcher.addToolArg("-p");
+            launcher.addToolArg(port);
+        }
+        if (serverName != null) {
+            launcher.addToolArg("-n");
+            launcher.addToolArg(serverName);
+        }
+
+        String[] cmd = launcher.getCommand();
+        log("Start jstatd", cmd);
+        return cmd;
+    }
+
+    private ProcessThread tryToSetupJstatdProcess() throws Throwable {
+        ProcessThread jstatdThread = new ProcessThread("Jstatd-Thread",
+                getJstatdCmd());
+        try {
+            jstatdThread.start();
+            // Make sure jstatd is up and running
+            jstatdPid = waitOnTool("jstatd", jstatdThread);
+            if (jstatdPid == null) {
+                // The port is already in use. Cancel and try with new one.
+                jstatdThread.stopProcess();
+                jstatdThread.join();
+                return null;
+            }
+        } catch (Throwable t) {
+            // Something went wrong in the product - clean up!
+            cleanUpThread(jstatdThread);
+            throw t;
+        }
+
+        return jstatdThread;
+    }
+
+    public void doTest() throws Throwable {
+        ProcessThread jstatdThread = null;
+        try {
+            while (jstatdThread == null) {
+                if (!useDefaultPort || withExternalRegistry) {
+                    port = Integer.toString(Utils.getFreePort());
+                }
+
+                if (withExternalRegistry) {
+                    Registry registry = startRegistry();
+                    if (registry == null) {
+                        // The port is already in use. Cancel and try with new one.
+                        continue;
+                    }
+                }
+
+                jstatdThread = tryToSetupJstatdProcess();
+            }
+
+            runToolsAndVerify();
+        } finally {
+            cleanUpThread(jstatdThread);
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/tools/jstatd/TestJstatdDefaults.java	Wed Oct 30 13:44:40 2013 +0100
@@ -0,0 +1,38 @@
+/*
+ * 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
+ * @bug 4990825
+ * @library /lib/testlibrary
+ * @build JstatdTest JstatGCUtilParser
+ * @run main/timeout=60 TestJstatdDefaults
+ */
+public class TestJstatdDefaults {
+
+    public static void main(String[] args) throws Throwable {
+        JstatdTest test = new JstatdTest();
+        test.doTest();
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/tools/jstatd/TestJstatdExternalRegistry.java	Wed Oct 30 13:44:40 2013 +0100
@@ -0,0 +1,39 @@
+/*
+ * 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
+ * @bug 4990825 7092186
+ * @library /lib/testlibrary
+ * @build JstatdTest JstatGCUtilParser
+ * @run main/timeout=60 TestJstatdExternalRegistry
+ */
+public class TestJstatdExternalRegistry {
+
+    public static void main(String[] args) throws Throwable {
+        JstatdTest test = new JstatdTest();
+        test.setWithExternalRegistry(true);
+        test.doTest();
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/tools/jstatd/TestJstatdPort.java	Wed Oct 30 13:44:40 2013 +0100
@@ -0,0 +1,39 @@
+/*
+ * 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
+ * @bug 4990825
+ * @library /lib/testlibrary
+ * @build JstatdTest JstatGCUtilParser
+ * @run main/timeout=60 TestJstatdPort
+ */
+public class TestJstatdPort {
+
+    public static void main(String[] args) throws Throwable {
+        JstatdTest test = new JstatdTest();
+        test.setUseDefaultPort(false);
+        test.doTest();
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/tools/jstatd/TestJstatdPortAndServer.java	Wed Oct 30 13:44:40 2013 +0100
@@ -0,0 +1,40 @@
+/*
+ * 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
+ * @bug 4990825
+ * @library /lib/testlibrary
+ * @build JstatdTest JstatGCUtilParser
+ * @run main/timeout=60 TestJstatdPortAndServer
+ */
+public class TestJstatdPortAndServer {
+
+    public static void main(String[] args) throws Throwable {
+        JstatdTest test = new JstatdTest();
+        test.setUseDefaultPort(false);
+        test.setServerName("TestJstatdServer");
+        test.doTest();
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/tools/jstatd/TestJstatdServer.java	Wed Oct 30 13:44:40 2013 +0100
@@ -0,0 +1,39 @@
+/*
+ * 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
+ * @bug 4990825
+ * @library /lib/testlibrary
+ * @build JstatdTest JstatGCUtilParser
+ * @run main/timeout=60 TestJstatdServer
+ */
+public class TestJstatdServer {
+
+    public static void main(String[] args) throws Throwable {
+        JstatdTest test = new JstatdTest();
+        test.setServerName("TestJstatdServer");
+        test.doTest();
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/tools/jstatd/TestJstatdUsage.java	Wed Oct 30 13:44:40 2013 +0100
@@ -0,0 +1,51 @@
+/*
+ * 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.
+ */
+
+import jdk.testlibrary.JDKToolLauncher;
+import jdk.testlibrary.OutputAnalyzer;
+
+/*
+ * @test
+ * @bug 4990825
+ * @library /lib/testlibrary
+ * @build jdk.testlibrary.JDKToolLauncher jdk.testlibrary.OutputAnalyzer
+ * @run main TestJstatdUsage
+ */
+public class TestJstatdUsage {
+
+    public static void main(String[] args) throws Exception {
+        testUsage("-help");
+        testUsage("-?");
+    }
+
+    private static void testUsage(String option) throws Exception {
+        JDKToolLauncher launcher = JDKToolLauncher.createUsingTestJDK("jstatd");
+        launcher.addToolArg(option);
+        ProcessBuilder processBuilder = new ProcessBuilder(launcher.getCommand());
+        OutputAnalyzer output = new OutputAnalyzer(processBuilder.start());
+
+        output.shouldContain("usage: jstatd [-nr] [-p port] [-n rminame]");
+        output.shouldHaveExitValue(1);
+    }
+
+}
--- a/jdk/test/sun/tools/jstatd/jpsOutput1.awk	Wed Oct 30 14:41:42 2013 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,27 +0,0 @@
-#
-BEGIN	{
-	    totallines=0; matched=0
-	}
-
-/^[0-9]+ [a-z|A-Z][a-z|A-Z|0-9|\$|\.]*$/	{
-	    matched++;
-	}
-
-/^[0-9]+ -- .*$/	{
-	    matched++;
-	}
-
-/^[0-9]+ $/	{
-	    matched++;
-	}
-
-	{ totallines++; print $0 }
-
-END	{
-	    if ((totallines > 0) && (matched == totallines)) {
-	        exit 0
-	    }
-	    else {
-	        exit 1
-	    }
-	}
--- a/jdk/test/sun/tools/jstatd/jstatGcutilOutput1.awk	Wed Oct 30 14:41:42 2013 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,34 +0,0 @@
-#
-# matching the following output specified as a pattern that verifies
-# that the numerical values conform to a specific pattern, rather than
-# specific values.
-#
-#  S0     S1     E      O      M     CCS    YGC     YGCT    FGC    FGCT     GCT   
-#  0.00 100.00  56.99   7.81  95.03  87.56      1    0.009     0    0.000    0.009
-#  0.00 100.00  63.64   7.81  95.03  87.56      1    0.009     0    0.000    0.009
-#  0.00 100.00  64.68   7.81  95.03  87.56      1    0.009     0    0.000    0.009
-#  0.00 100.00  65.73   7.81  95.03  87.56      1    0.009     0    0.000    0.009
-#  0.00 100.00  67.22   7.81  95.03  87.56      1    0.009     0    0.000    0.009
-
-BEGIN	{
-	    headerlines=0; datalines=0; totallines=0
-	}
-
-/^  S0     S1     E      O      M     CCS    YGC     YGCT    FGC    FGCT     GCT   $/	{
-	    headerlines++;
-	}
-
-/^[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*([0-9]+\.[0-9]+)|-[ ]*[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+[ ]*[0-9]+\.[0-9]+[ ]*[0-9]+\.[0-9]+$/	{
-	    datalines++;
-	}
-
-	{ totallines++; print $0 }
-
-END	{
-	    if ((headerlines == 1) && (datalines == 5) && (totallines == 6)) {
-	        exit 0
-            }
-            else {
-	        exit 1
-            }
-	}
--- a/jdk/test/sun/tools/jstatd/jstatdDefaults.sh	Wed Oct 30 14:41:42 2013 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,79 +0,0 @@
-#
-# Copyright (c) 2004, 2012, 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 4990825
-# @run shell/timeout=60 jstatdDefaults.sh
-# @summary Test functionality of 'jstatd &'
-
-. ${TESTSRC-.}/../../jvmstat/testlibrary/utils.sh
-
-setup
-verify_os
-
-cleanup() {
-  kill_proc ${JSTATD_PID}
-}
-
-trap 'cleanup' 0 HUP INT QUIT TERM
-
-JSTATD="${TESTJAVA}/bin/jstatd"
-JPS="${TESTJAVA}/bin/jps"
-JSTAT="${TESTJAVA}/bin/jstat"
-
-HOSTNAME=`uname -n`
-
-JSTATD_OUT="jstatd_$$.out"
-
-${JSTATD} -J-XX:+UsePerfData -J-Djava.security.policy=${TESTSRC}/all.policy 2>&1 > ${JSTATD_OUT} &
-JSTATD_PID=$!
-
-echo "jstatd started as pid ${JSTATD_PID}"
-sleep 3
-
-${JPS} -J-XX:+UsePerfData ${HOSTNAME} 2>&1 | awk -f ${TESTSRC}/jpsOutput1.awk
-
-if [ $? -ne 0 ]
-then
-    echo "Output of jps differs from expected output. Failed."
-    cleanup
-    exit 1
-fi
-
-${JSTAT} -J-XX:+UsePerfData -J-Duser.language=en -gcutil ${JSTATD_PID}@${HOSTNAME} 250 5 2>&1 | awk -f ${TESTSRC}/jstatGcutilOutput1.awk
-RC=$?
-
-if [ ${RC} -ne 0 ]
-then
-    echo "jstat output differs from expected output"
-fi
-
-if [ -s ${JSTATD_OUT} ]
-then
-    echo "jstatd generated the following, unexpected output:"
-    RC=1
-fi
-
-cleanup
-
-exit ${RC}
--- a/jdk/test/sun/tools/jstatd/jstatdExternalRegistry.sh	Wed Oct 30 14:41:42 2013 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,96 +0,0 @@
-#
-# Copyright (c) 2004, 2012, 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 4990825 7092186
-# @run shell/timeout=90 jstatdExternalRegistry.sh
-# @summary Test functionality of 'jstatd -p<port>&' with an external RMI registry
-
-. ${TESTSRC-.}/../../jvmstat/testlibrary/utils.sh
-
-setup
-verify_os
-
-cleanup() {
-  kill_proc ${RMIREGISTRY_PID}
-  kill_proc ${JSTATD_PID}
-}
-
-trap 'cleanup' 0 HUP INT QUIT TERM
-
-RMIREGISTRY="${TESTJAVA}/bin/rmiregistry"
-JSTATD="${TESTJAVA}/bin/jstatd"
-JPS="${TESTJAVA}/bin/jps"
-JSTAT="${TESTJAVA}/bin/jstat"
-
-HOSTNAME=`uname -n`
-PORT=`freePort`
-if [ "${PORT}" = "0" ] ; then
-  echo "Cannot get free port"
-  exit 1
-fi
-
-RMIREGISTRY_OUT="rmiregistry_$$.out"
-JSTATD_OUT="jstatd_$$.out"
-
-${RMIREGISTRY} -J-XX:+UsePerfData ${PORT} > ${RMIREGISTRY_OUT} 2>&1 &
-RMIREGISTRY_PID=$!
-
-echo "rmiregistry started on port ${PORT} as pid ${RMIREGISTRY_PID}"
-sleep 3
-
-${JSTATD} -J-XX:+UsePerfData -J-Djava.security.policy=${TESTSRC}/all.policy -p ${PORT} > ${JSTATD_OUT} 2>&1 &
-JSTATD_PID=$!
-
-echo "jstatd started as pid ${JSTATD_PID}"
-sleep 3
-
-${JPS} -J-XX:+UsePerfData ${HOSTNAME}:${PORT} 2>&1 | awk -f ${TESTSRC}/jpsOutput1.awk
-
-if [ $? -ne 0 ]
-then
-    echo "Output of jps differs from expected output. Failed."
-    exit 1
-fi
-
-${JSTAT} -J-XX:+UsePerfData -J-Duser.language=en -gcutil ${JSTATD_PID}@${HOSTNAME}:${PORT} 250 5 2>&1 | awk -f ${TESTSRC}/jstatGcutilOutput1.awk
-RC=$?
-
-if [ ${RC} -ne 0 ]
-then
-    echo "jstat output differs from expected output"
-fi
-
-if [ -s ${JSTATD_OUT} ]
-then
-    echo "jstatd generated unexpected output: see ${JSTATD_OUT}"
-    RC=1
-fi
-
-if [ -s ${RMIREGISTRY_OUT} ]
-then
-    echo "rmiregistry generated unexpected output: see ${RMIREGISTRY_OUT}"
-    RC=1
-fi
-
-exit ${RC}
--- a/jdk/test/sun/tools/jstatd/jstatdPort.sh	Wed Oct 30 14:41:42 2013 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,84 +0,0 @@
-#
-# Copyright (c) 2004, 2012, 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 4990825
-# @run shell/timeout=60 jstatdPort.sh
-# @summary Test functionality of 'jstatd -p <port>&'
-
-. ${TESTSRC-.}/../../jvmstat/testlibrary/utils.sh
-
-setup
-verify_os
-
-cleanup() {
-  kill_proc ${JSTATD_PID}
-}
-
-trap 'cleanup' 0 HUP INT QUIT TERM
-
-JSTATD="${TESTJAVA}/bin/jstatd"
-JPS="${TESTJAVA}/bin/jps"
-JSTAT="${TESTJAVA}/bin/jstat"
-
-HOSTNAME=`uname -n`
-PORT=`freePort`
-if [ "${PORT}" = "0" ] ; then
-  echo "Cannot get free port"
-  exit 1
-fi
-
-JSTATD_OUT="jstatd_$$.out"
-
-${JSTATD} -J-XX:+UsePerfData -J-Djava.security.policy=${TESTSRC}/all.policy -p ${PORT} 2>&1 > ${JSTATD_OUT} &
-JSTATD_PID=$!
-
-echo "jstatd started as pid ${JSTATD_PID} on port ${PORT}"
-sleep 3
-
-${JPS} -J-XX:+UsePerfData ${HOSTNAME}:${PORT} 2>&1 | tee jps.out | awk -f ${TESTSRC}/jpsOutput1.awk
-
-if [ $? -ne 0 ]
-then
-    echo "Output of jps differs from expected output. Failed."
-    cleanup
-    exit 1
-fi
-
-${JSTAT} -J-XX:+UsePerfData -J-Duser.language=en -gcutil ${JSTATD_PID}@${HOSTNAME}:${PORT} 250 5 2>&1 | awk -f ${TESTSRC}/jstatGcutilOutput1.awk
-RC=$?
-
-if [ ${RC} -ne 0 ]
-then
-    echo "jstat output differs from expected output"
-fi
-
-if [ -s ${JSTATD_OUT} ]
-then
-    echo "jstatd generated the following, unexpected output:"
-    RC=1
-fi
-
-cleanup
-
-exit ${RC}
--- a/jdk/test/sun/tools/jstatd/jstatdServerName.sh	Wed Oct 30 14:41:42 2013 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,121 +0,0 @@
-#
-# Copyright (c) 2004, 2012, 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 4990825
-# @run shell/timeout=90 jstatdServerName.sh
-# @summary Test functionality of 'jstatd -p <port> -n <servername>&'
-
-. ${TESTSRC-.}/../../jvmstat/testlibrary/utils.sh
-
-setup
-verify_os
-
-cleanup() {
-  kill_proc ${JSTATD_1_PID}
-  kill_proc ${JSTATD_2_PID}
-}
-
-trap 'cleanup' 0 HUP INT QUIT TERM
-
-JSTATD="${TESTJAVA}/bin/jstatd"
-JPS="${TESTJAVA}/bin/jps"
-JSTAT="${TESTJAVA}/bin/jstat"
-
-HOSTNAME=`uname -n`
-PORT_1=`freePort`
-if [ "${PORT_1}" = "0" ] ; then
-  echo "ERROR: No free port"
-  exit 1
-fi
-PORT_2=`expr ${PORT_1} '+' 1`
-SERVERNAME="SecondJstatdServer"
-
-JSTATD_1_OUT="jstatd_$$_1.out"
-JSTATD_2_OUT="jstatd_$$_2.out"
-
-${JSTATD} -J-XX:+UsePerfData -J-Djava.security.policy=${TESTSRC}/all.policy -p ${PORT_1} 2>&1 > ${JSTATD_1_OUT} &
-JSTATD_1_PID=$!
-
-echo "first jstatd started as pid ${JSTATD_1_PID} on port ${PORT_1} with default server name"
-sleep 3
-
-${JSTATD} -J-XX:+UsePerfData -J-Djava.security.policy=${TESTSRC}/all.policy -p ${PORT_2} -n ${SERVERNAME} 2>&1 > ${JSTATD_2_OUT} &
-JSTATD_2_PID=$!
-
-echo "second jstatd started as pid ${JSTATD_2_PID} on port ${PORT_2} with name ${SERVERNAME}"
-sleep 3
-
-echo "running: ${JPS} -J-XX:+UsePerfData ${HOSTNAME}:${PORT_1}"
-${JPS} -J-XX:+UsePerfData ${HOSTNAME}:${PORT_1} 2>&1 | awk -f ${TESTSRC}/jpsOutput1.awk
-
-if [ $? -ne 0 ]
-then
-    echo "Output of jps differs from expected output. Failed."
-    cleanup
-    exit 1
-fi
-
-echo "running: ${JPS} -J-XX:+UsePerfData ${HOSTNAME}:${PORT_2}/${SERVERNAME}"
-${JPS} -J-XX:+UsePerfData ${HOSTNAME}:${PORT_2}/${SERVERNAME} 2>&1 | awk -f ${TESTSRC}/jpsOutput1.awk
-
-if [ $? -ne 0 ]
-then
-    echo "Output of jps differs from expected output. Failed."
-    cleanup
-    exit 1
-fi
-
-echo "running: ${JSTAT} -J-XX:+UsePerfData -J-Duser.language=en -gcutil ${JSTATD_1_PID}@${HOSTNAME}:${PORT_1} 250 5"
-${JSTAT} -J-XX:+UsePerfData -J-Duser.language=en -gcutil ${JSTATD_1_PID}@${HOSTNAME}:${PORT_1} 250 5 2>&1 | awk -f ${TESTSRC}/jstatGcutilOutput1.awk
-RC=$?
-
-if [ ${RC} -ne 0 ]
-then
-    echo "jstat output differs from expected output"
-fi
-
-echo "running: ${JSTAT} -J-XX:+UsePerfData -J-Duser.language=en -gcutil ${JSTATD_1_PID}@${HOSTNAME}:${PORT_2}/${SERVERNAME} 250 5"
-${JSTAT} -J-XX:+UsePerfData -J-Duser.language=en -gcutil ${JSTATD_1_PID}@${HOSTNAME}:${PORT_2}/${SERVERNAME} 250 5 2>&1 | awk -f ${TESTSRC}/jstatGcutilOutput1.awk
-RC=$?
-
-if [ ${RC} -ne 0 ]
-then
-    echo "jstat output differs from expected output"
-fi
-
-if [ -s ${JSTATD_1_OUT} ]
-then
-    echo "first jstatd generated the following, unexpected output:"
-    RC=1
-fi
-
-if [ -s ${JSTATD_2_OUT} ]
-then
-    echo "second jstatd generated the following, unexpected output:"
-    RC=1
-fi
-
-cleanup
-
-exit ${RC}
--- a/jdk/test/sun/tools/jstatd/jstatdUsage1.sh	Wed Oct 30 14:41:42 2013 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,56 +0,0 @@
-#
-# Copyright (c) 2004, 2010, 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 4990825
-# @run shell jstatdUsage1.sh
-# @summary Test that output of 'jstatd -help' matches the usage.out file
-
-. ${TESTSRC-.}/../../jvmstat/testlibrary/utils.sh
-
-setup
-
-JSTATD="${TESTJAVA}/bin/jstatd"
-
-JSTATD_1_OUT="jstatd_$$_1.out"
-JSTATD_2_OUT="jstatd_$$_2.out"
-
-${JSTATD} -? > ${JSTATD_1_OUT} 2>&1
-
-diff -w ${JSTATD_1_OUT} ${TESTSRC}/usage.out
-if [ $? != 0 ]
-then
-  echo "Output of jstatd -? differs from expected output. Failed."
-  exit 1
-fi
-
-${JSTATD} -help > ${JSTATD_2_OUT} 2>&1
-
-diff -w ${JSTATD_2_OUT} ${TESTSRC}/usage.out
-if [ $? != 0 ]
-then
-  echo "Output of jstatd -help differs from expected output. Failed."
-  exit 1
-fi
-
-exit 0
--- a/jdk/test/sun/tools/jstatd/usage.out	Wed Oct 30 14:41:42 2013 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-usage: jstatd [-nr] [-p port] [-n rminame]