Staffan,

The webrev with changes can be found here:
http://cr.openjdk.java.net/~ykantser/7185591/webrev.02/

If it looks good, could you please be my sponsor and push the changes? The patch is attached to this mail.

Thanks,
Katja



On 01/15/2014 11:37 AM, Staffan Larsen wrote:
Katja,

test/lib/testlibrary/jdk/testlibrary/JcmdBase.java
The toolArgs parameter should be renamed jcmdArgs.

test/lib/testlibrary/jdk/testlibrary/OutputAnalyzer.java
423     public int indexOf(String pattern) {
You don’t have to convert the List to an array before iterating through it. Use lLines.get(i).matches(…) instead.

470 public int shouldMatchByLine(String from, String to, String pattern) { This method still reads the lines into an ArrayList (at most) three times. It calls asLines() once and indexOf() twice. There could be a version of indexOf() that takes a List<String>. Actually indexOf could be private and always take a List<String>.


Otherwise ok!

/Staffan



On 15 jan 2014, at 10:13, Yekaterina Kantserova <yekaterina.kantser...@oracle.com <mailto:yekaterina.kantser...@oracle.com>> wrote:

Staffan, thank you for pointing out performance and test.src issues!

The webrev with fixes can be found here:
http://cr.openjdk.java.net/~ykantser/7185591/webrev.01/ <http://cr.openjdk.java.net/%7Eykantser/7185591/webrev.01/>

Please, see my comments in-lined.

Thanks,
Katja



On 01/13/2014 01:19 PM, Staffan Larsen wrote:
Katja,

test/lib/testlibrary/jdk/testlibrary/JcmdBase.java
 68      * Run jcmd standalone

I think you should expand a bit on what “standalone” means here. It took me a while to understand the difference.
Fixed.

test/lib/testlibrary/jdk/testlibrary/OutputAnalyzer.java
423     public int indexOf(String pattern) {

This seems very inefficient. Add all lines to an ArrayList and then walk through them one at a time to if it matches and then walk through them once again to find the index of that line.

469 public int shouldMatchByLine(String from, String to, String pattern) {

Same inefficiency here, but worse because both asLines() and indexOf() does the same work.

test/lib/testlibrary/jdk/testlibrary/Utils.java
65 public static final String TEST_SRC = System.getProperty("test.src").trim();
Fixed.

I wonder if this really works. Isn’t “test.src” different for different tests? A property that jtreg changes
Yes, it is different.
before invoking each test? Or does this work because each test is run in a different class loader and Utils.java will exist once in each class loader?
I've learned now it works because jtreg compiles all classes a test needs to a separate location. For example when I run TestJcmdDefaults there will be both TestJcmdDefaults.class and jdk/testlibrary/Utils.class under /tmp/jtreg/jtreg-workdir/classes/sun/tools/jcmd/. The class loader will load Utils for TestJcmdDefaults from /tmp/jtreg/jtreg-workdir/classes/sun/tools/jcmd/.

...
[Loaded jdk.testlibrary.Utils from file:/tmp/jtreg/jtreg-workdir/classes/sun/tools/jcmd/]
...

But I think it's better to declare TEST_SRC per test precisely because it's different for different tests.



/Staffan


On 10 jan 2014, at 13:50, Yekaterina Kantserova <yekaterina.kantser...@oracle.com <mailto:yekaterina.kantser...@oracle.com>> wrote:

Hi,

Could I please have a review of this fix.

In this fix I've rewritten sun/tools/jcmd/* tests in pure java to get rid of all intermittent failures depending on for example MKS or race conditions (test application has not yet started when the test start to run).


Webrev:
http://cr.openjdk.java.net/~ykantser/7185591/webrev.00/ <http://cr.openjdk.java.net/%7Eykantser/7185591/webrev.00/>

Primal bug:
https://bugs.openjdk.java.net/browse/JDK-7185591

Similar bugs:
https://bugs.openjdk.java.net/browse/JDK-6977426
https://bugs.openjdk.java.net/browse/JDK-8020798
https://bugs.openjdk.java.net/browse/JDK-7130656 (this one is blocked by https://bugs.openjdk.java.net/browse/JDK-8031482 so far)

Thanks,
Katja


# HG changeset patch
# User ykantser
# Date 1389791523 -3600
# Node ID 8f80cea368b700dcfba912cbc4297c4a3a8c63b0
# Parent  322a13ba1def144b685b52e7494eec45823fec31
7185591: jcmd-big-script.sh ERROR: could not find app's Java pid.
Reviewed-by: egahlin, sla, jbachorik

diff --git a/test/ProblemList.txt b/test/ProblemList.txt
--- a/test/ProblemList.txt
+++ b/test/ProblemList.txt
@@ -277,3 +277,10 @@
 # jdk_util
 
 ############################################################################
+
+# svc_tools
+
+# 8031482
+sun/tools/jcmd/TestJcmdSanity.java				windows-all
+
+############################################################################
diff --git a/test/lib/testlibrary/jdk/testlibrary/JcmdBase.java b/test/lib/testlibrary/jdk/testlibrary/JcmdBase.java
--- a/test/lib/testlibrary/jdk/testlibrary/JcmdBase.java
+++ b/test/lib/testlibrary/jdk/testlibrary/JcmdBase.java
@@ -26,34 +26,91 @@
 import java.util.Arrays;
 
 /**
- * Super class for tests which need to attach jcmd to the current process.
+ * Helper class for starting jcmd process.
+ * <pre>
+ * - jcmd will send diagnostic requests to the current java process:
+ *      jcmd pid_to_current_process PerfCounter.print
+ * - jcmd will be run without sending request to any JVM
+ *      jcmd -h
+ * </pre>
  */
-public class JcmdBase {
+public final class JcmdBase {
 
     private static ProcessBuilder processBuilder = new ProcessBuilder();
 
+    private JcmdBase() {
+        // Private constructor to prevent class instantiation
+    }
+
     /**
-     * Attach jcmd to the current process
+     * Sends the diagnostic command request to the current process
      *
-     * @param toolArgs
-     *            jcmd command line parameters, e.g. VM.flags
-     * @return jcmd output
-     * @throws Exception
+     * @see #jcmd(boolean, String[], String[])
      */
     public final static OutputAnalyzer jcmd(String... toolArgs)
             throws Exception {
+        return jcmd(true, null, toolArgs);
+    }
+
+    /**
+     * Sends the diagnostic command request to the current process.
+     * jcmd will be run with specified {@code vmArgs}.
+     *
+     * @see #jcmd(boolean, String[], String[])
+     */
+    public final static OutputAnalyzer jcmd(String[] vmArgs,
+            String[] toolArgs) throws Exception {
+        return jcmd(true, vmArgs, toolArgs);
+    }
+
+    /**
+     * Runs jcmd without sending request to any JVM
+     *
+     * @see #jcmd(boolean, String[], String[])
+     */
+    public final static OutputAnalyzer jcmdNoPid(String[] vmArgs,
+            String[] toolArgs) throws Exception {
+        return jcmd(false, vmArgs, toolArgs);
+    }
+
+    /**
+     * If {@code requestToCurrentProcess} is {@code true}
+     * sends a diagnostic command request to the current process.
+     * If {@code requestToCurrentProcess} is {@code false}
+     * runs jcmd without sending request to any JVM.
+     *
+     * @param requestToCurrentProcess
+     *            Defines if jcmd will send request to the current process
+     * @param vmArgs
+     *            jcmd will be run with VM arguments specified,
+     *            e.g. -XX:+UsePerfData
+     * @param toolArgs
+     *            jcmd will be run with option or command and its arguments
+     *            specified, e.g. VM.flags
+     * @return The output from {@link OutputAnalyzer} object
+     * @throws Exception
+     */
+    private static final OutputAnalyzer jcmd(boolean requestToCurrentProcess,
+            String[] vmArgs, String[] toolArgs) throws Exception {
         JDKToolLauncher launcher = JDKToolLauncher.createUsingTestJDK("jcmd");
-        launcher.addToolArg(Integer.toString(ProcessTools.getProcessId()));
-        for (String toolArg : toolArgs) {
-            launcher.addToolArg(toolArg);
+        if (vmArgs != null) {
+            for (String vmArg : vmArgs) {
+                launcher.addVMArg(vmArg);
+            }
+        }
+        if (requestToCurrentProcess) {
+            launcher.addToolArg(Integer.toString(ProcessTools.getProcessId()));
+        }
+        if (toolArgs != null) {
+            for (String toolArg : toolArgs) {
+                launcher.addToolArg(toolArg);
+            }
         }
         processBuilder.command(launcher.getCommand());
         System.out.println(Arrays.toString(processBuilder.command().toArray()).replace(",", ""));
         OutputAnalyzer output = new OutputAnalyzer(processBuilder.start());
         System.out.println(output.getOutput());
 
-        output.shouldHaveExitValue(0);
-
         return output;
     }
 
diff --git a/test/lib/testlibrary/jdk/testlibrary/OutputAnalyzer.java b/test/lib/testlibrary/jdk/testlibrary/OutputAnalyzer.java
--- a/test/lib/testlibrary/jdk/testlibrary/OutputAnalyzer.java
+++ b/test/lib/testlibrary/jdk/testlibrary/OutputAnalyzer.java
@@ -23,7 +23,11 @@
 
 package jdk.testlibrary;
 
+import static jdk.testlibrary.Asserts.*;
+
 import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
@@ -394,4 +398,99 @@
     public int getExitValue() {
         return exitValue;
     }
+
+    /**
+     * Get the contents of the output buffer (stdout and stderr) as list of strings.
+     * Output will be split by system property 'line.separator'.
+     *
+     * @return Contents of the output buffer as list of strings
+     */
+    public List<String> asLines() {
+        List<String> l = new ArrayList<>();
+        String[] a = getOutput().split(Utils.NEW_LINE);
+        for (String string : a) {
+            l.add(string);
+        }
+        return l;
+    }
+
+    /**
+     * Check if there is a line matching {@code pattern} and return its index
+     *
+     * @param pattern Matching pattern
+     * @return Index of first matching line
+     */
+    private int indexOf(List<String> lines, String pattern) {
+        for (int i = 0; i < lines.size(); i++) {
+            if (lines.get(i).matches(pattern)) {
+                return i;
+            }
+        }
+        return -1;
+    }
+
+    /**
+     * @see #shouldMatchByLine(String, String, String)
+     */
+    public int shouldMatchByLine(String pattern) {
+        return shouldMatchByLine(null, null, pattern);
+    }
+
+    /**
+     * @see #shouldMatchByLine(String, String, String)
+     */
+    public int shouldMatchByLineFrom(String from, String pattern) {
+        return shouldMatchByLine(from, null, pattern);
+    }
+
+    /**
+     * @see #shouldMatchByLine(String, String, String)
+     */
+    public int shouldMatchByLineTo(String to, String pattern) {
+        return shouldMatchByLine(null, to, pattern);
+    }
+
+    /**
+     * Verify that the stdout and stderr contents of output buffer match the
+     * {@code pattern} line by line. The whole output could be matched or
+     * just a subset of it.
+     *
+     * @param from
+     *            The line from where output will be matched.
+     *            Set {@code from} to null for matching from the first line.
+     * @param to
+     *            The line until where output will be matched.
+     *            Set {@code to} to null for matching until the last line.
+     * @param pattern
+     *            Matching pattern
+     * @return Count of lines which match the {@code pattern}
+     */
+    public int shouldMatchByLine(String from, String to, String pattern) {
+        List<String> lines = asLines();
+
+        int fromIndex = 0;
+        if (from != null) {
+            fromIndex = indexOf(lines, from);
+            assertGreaterThan(fromIndex, -1,
+                    "The line/pattern '" + from + "' from where the output should match can not be found");
+        }
+
+        int toIndex = lines.size();
+        if (to != null) {
+            toIndex = indexOf(lines, to);
+            assertGreaterThan(toIndex, -1,
+                    "The line/pattern '" + to + "' until where the output should match can not be found");
+        }
+
+        List<String> subList = lines.subList(fromIndex, toIndex);
+        int matchedCount = 0;
+        for (String line : subList) {
+            assertTrue(line.matches(pattern),
+                    "The line '" + line + "' does not match pattern '" + pattern + "'");
+            matchedCount++;
+        }
+
+        return matchedCount;
+    }
+
 }
diff --git a/test/lib/testlibrary/jdk/testlibrary/Utils.java b/test/lib/testlibrary/jdk/testlibrary/Utils.java
--- a/test/lib/testlibrary/jdk/testlibrary/Utils.java
+++ b/test/lib/testlibrary/jdk/testlibrary/Utils.java
@@ -25,6 +25,9 @@
 
 import static jdk.testlibrary.Asserts.assertTrue;
 
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
 import java.io.IOException;
 import java.net.InetAddress;
 import java.net.ServerSocket;
@@ -56,7 +59,6 @@
      */
     public static final String JAVA_OPTIONS = System.getProperty("test.java.opts", "").trim();
 
-
     private Utils() {
         // Private constructor to prevent class instantiation
     }
@@ -203,7 +205,6 @@
      * @throws Exception If multiple matching jvms are found.
      */
     public static int tryFindJvmPid(String key) throws Throwable {
-        ProcessBuilder pb = null;
         OutputAnalyzer output = null;
         try {
             JDKToolLauncher jcmdLauncher = JDKToolLauncher.create("jcmd");
@@ -229,4 +230,24 @@
             throw t;
         }
     }
+
+    /**
+     * Returns file content as a list of strings
+     *
+     * @param file File to operate on
+     * @return List of strings
+     * @throws IOException
+     */
+    public static List<String> fileAsList(File file) throws IOException {
+        assertTrue(file.exists() && file.isFile(),
+                file.getAbsolutePath() + " does not exist or not a file");
+        List<String> output = new ArrayList<>();
+        try (BufferedReader reader = new BufferedReader(new FileReader(file.getAbsolutePath()))) {
+            while (reader.ready()) {
+                output.add(reader.readLine().replace(NEW_LINE, ""));
+            }
+        }
+        return output;
+    }
+
 }
diff --git a/test/sun/tools/jcmd/TestJcmdDefaults.java b/test/sun/tools/jcmd/TestJcmdDefaults.java
new file mode 100644
--- /dev/null
+++ b/test/sun/tools/jcmd/TestJcmdDefaults.java
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2011, 2014, 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 static jdk.testlibrary.Asserts.*;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.List;
+
+import jdk.testlibrary.JcmdBase;
+import jdk.testlibrary.OutputAnalyzer;
+import jdk.testlibrary.Utils;
+
+/**
+ * Unit test for jcmd utility. Tests jcmd options which do not send
+ * requests to a specific JVM process.
+ */
+/*
+ * @test
+ * @bug 7104647
+ * @library /lib/testlibrary
+ * @run main TestJcmdDefaults
+ */
+public class TestJcmdDefaults {
+
+    private static final String TEST_SRC = System.getProperty("test.src").trim();
+    private static final String[] VM_ARGS = new String[] { "-XX:+UsePerfData" };
+    private static final String JCMD_LIST_REGEX = "^\\d+\\s*.*";
+
+    public static void main(String[] args) throws Exception {
+        testJcmdUsage("-h");
+        testJcmdUsage("-help");
+        testJcmdDefaults();
+        testJcmdDefaults("-l");
+    }
+
+    /**
+     * jcmd -J-XX:+UsePerfData -h
+     * jcmd -J-XX:+UsePerfData -help
+     */
+    private static void testJcmdUsage(String... toolArgs) throws Exception {
+        OutputAnalyzer output = JcmdBase.jcmdNoPid(VM_ARGS, toolArgs);
+
+        assertNotEquals(output.getExitValue(), 0);
+        verifyOutputAgainstFile(output);
+    }
+
+    /**
+     * jcmd -J-XX:+UsePerfData
+     * jcmd -J-XX:+UsePerfData -l
+     */
+    private static void testJcmdDefaults(String... toolArgs) throws Exception {
+        OutputAnalyzer output = JcmdBase.jcmdNoPid(VM_ARGS, toolArgs);
+
+        output.shouldHaveExitValue(0);
+        output.shouldContain("sun.tools.jcmd.JCmd");
+        matchListedProcesses(output);
+    }
+
+    /**
+     * Verifies the listed processes match a certain pattern.
+     *
+     * The output should look like:
+     * 12246 sun.tools.jcmd.JCmd
+     * 24428 com.sun.javatest.regtest.MainWrapper /tmp/jtreg/jtreg-workdir/classes/sun/tools/jcmd/TestJcmdDefaults.jta
+     *
+     * @param output The generated output from the jcmd.
+     * @throws Exception
+     */
+    private static void matchListedProcesses(OutputAnalyzer output) throws Exception {
+        int matchedCount = output.shouldMatchByLine(JCMD_LIST_REGEX);
+        assertGreaterThan(matchedCount , 0,
+                "Found no lines matching pattern: " + JCMD_LIST_REGEX);
+    }
+
+    private static void verifyOutputAgainstFile(OutputAnalyzer output) throws IOException {
+        File file = new File(TEST_SRC, "usage.out");
+        List<String> fileOutput = Utils.fileAsList(file);
+        List<String> outputAsLines = output.asLines();
+        assertTrue(outputAsLines.containsAll(fileOutput),
+                "The ouput should contain all content of " + file.getAbsolutePath());
+    }
+
+}
diff --git a/test/sun/tools/jcmd/TestJcmdSanity.java b/test/sun/tools/jcmd/TestJcmdSanity.java
new file mode 100644
--- /dev/null
+++ b/test/sun/tools/jcmd/TestJcmdSanity.java
@@ -0,0 +1,169 @@
+/*
+ * Copyright (c) 2011, 2014, 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 static jdk.testlibrary.Asserts.*;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.List;
+
+import jdk.testlibrary.JcmdBase;
+import jdk.testlibrary.OutputAnalyzer;
+import jdk.testlibrary.ProcessTools;
+import jdk.testlibrary.Utils;
+
+/**
+ * Unit test for jcmd utility. The test will send different diagnostic command
+ * requests to the current java process.
+ */
+/*
+ * @test
+ * @bug 7104647 7154822
+ * @library /lib/testlibrary
+ * @run main TestJcmdSanity
+ */
+public class TestJcmdSanity {
+
+    private static final String TEST_SRC = System.getProperty("test.src").trim();
+    private static final String[] VM_ARGS = new String[] { "-XX:+UsePerfData" };
+    private static final String JCMD_COMMAND_REGEX = "(\\w|\\.)*";
+    private static final String PERF_COUNTER_REGEX = "(\\w|\\.)*\\=.*";
+
+    public static void main(String[] args) throws Exception {
+        testJcmdPidHelp();
+        testJcmdPidHelpHelp();
+        testJcmdPid_f();
+        testJcmdPidPerfCounterPrint();
+        testJcmdPidBigScript();
+    }
+
+    /**
+     * jcmd -J-XX:+UsePerfData pid help
+     */
+    private static void testJcmdPidHelp() throws Exception {
+        OutputAnalyzer output = JcmdBase.jcmd(VM_ARGS,
+                new String[] {"help"});
+
+        output.shouldHaveExitValue(0);
+        output.shouldNotContain("Exception");
+        output.shouldContain(Integer.toString(ProcessTools.getProcessId()) + ":");
+        matchJcmdCommands(output);
+        output.shouldContain("For more information about a specific command use 'help <command>'.");
+    }
+
+    /**
+     * jcmd -J-XX:+UsePerfData pid help help
+     */
+    private static void testJcmdPidHelpHelp() throws Exception {
+        OutputAnalyzer output = JcmdBase.jcmd(VM_ARGS,
+                new String[] {"help", "help"});
+
+        output.shouldHaveExitValue(0);
+        verifyOutputAgainstFile(output);
+    }
+
+    /**
+     * jcmd -J-XX:+UsePerfData pid PerfCounter.print
+     */
+    private static void testJcmdPidPerfCounterPrint() throws Exception {
+        OutputAnalyzer output = JcmdBase.jcmd(VM_ARGS,
+                new String[] {"PerfCounter.print"});
+
+        output.shouldHaveExitValue(0);
+        matchPerfCounters(output);
+    }
+
+    /**
+     * jcmd -J-XX:+UsePerfData pid -f dcmd-script.txt
+     */
+    private static void testJcmdPid_f() throws Exception {
+        File scrpitFile = new File(TEST_SRC, "dcmd-script.txt");
+        OutputAnalyzer output = JcmdBase.jcmd(VM_ARGS,
+                new String[] {"-f", scrpitFile.getAbsolutePath()});
+
+        output.shouldHaveExitValue(0);
+        verifyOutputAgainstFile(output);
+    }
+
+    /**
+     * Tests that it possible send a file over 1024 bytes large via jcmd -f.
+     *
+     * jcmd -J-XX:+UsePerfData pid -f dcmd-big-script.txt
+     */
+    private static void testJcmdPidBigScript() throws Exception {
+        File scrpitFile = new File(TEST_SRC, "dcmd-big-script.txt");
+        OutputAnalyzer output = JcmdBase.jcmd(VM_ARGS,
+                new String[] {"-f", scrpitFile.getAbsolutePath()});
+
+        output.shouldHaveExitValue(0);
+        output.shouldNotContain("Exception");
+        output.shouldContain(System.getProperty("java.vm.name").trim());
+    }
+
+    /**
+     * Verifies the listed jcmd commands match a certain pattern.
+     *
+     * The output of the jcmd commands should look like:
+     * VM.uptime
+     * VM.flags
+     * VM.system_properties
+     *
+     * @param output The generated output from the jcmd.
+     * @throws Exception
+     */
+    private static void matchJcmdCommands(OutputAnalyzer output) throws Exception {
+        int matchedCount = output.shouldMatchByLine(JCMD_COMMAND_REGEX,
+                "help",
+                JCMD_COMMAND_REGEX);
+        assertGreaterThan(matchedCount , 0,
+                "Found no lines matching pattern: " + JCMD_COMMAND_REGEX);
+    }
+
+    /**
+     * Verifies the generated output from the PerfCounter.print command
+     * matches a certain pattern.
+     *
+     * The output of perf counters should look like:
+     * java.property.java.vm.name="Java HotSpot(TM) 64-Bit Server VM"
+     * java.threads.daemon=7
+     * sun.rt.javaCommand="com.sun.javatest.regtest.MainWrapper /tmp/jtreg/jtreg-workdir/classes/sun/tools/jcmd/TestJcmdSanity.jta"
+     *
+     * @param output The generated output from the PerfCounter.print command.
+     * @throws Exception
+     */
+    private static void matchPerfCounters(OutputAnalyzer output) throws Exception {
+        int matchedCount = output.shouldMatchByLineFrom(PERF_COUNTER_REGEX,
+                PERF_COUNTER_REGEX);
+        assertGreaterThan(matchedCount , 0,
+                "Found no lines matching pattern: " + PERF_COUNTER_REGEX);
+    }
+
+    private static void verifyOutputAgainstFile(OutputAnalyzer output) throws IOException {
+        File file = new File(TEST_SRC, "help_help.out");
+        List<String> fileOutput = Utils.fileAsList(file);
+        List<String> outputAsLines = output.asLines();
+        assertTrue(outputAsLines.containsAll(fileOutput),
+                "The ouput should contain all content of " + file.getAbsolutePath());
+    }
+
+}
diff --git a/test/sun/tools/jcmd/help_help.out b/test/sun/tools/jcmd/help_help.out
--- a/test/sun/tools/jcmd/help_help.out
+++ b/test/sun/tools/jcmd/help_help.out
@@ -1,7 +1,7 @@
 help
 For more information about a specific command use 'help <command>'. With no argument this will show a list of available commands. 'help all' will show help for all commands.
 
-Impact: Low 
+Impact: Low
 
 Syntax : help [options] [<command name>]
 
diff --git a/test/sun/tools/jcmd/jcmd-Defaults.sh b/test/sun/tools/jcmd/jcmd-Defaults.sh
deleted file mode 100644
--- a/test/sun/tools/jcmd/jcmd-Defaults.sh
+++ /dev/null
@@ -1,33 +0,0 @@
-#
-# Copyright (c) 2011, 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 7104647
-# @run shell jcmd-Defaults.sh
-# @summary Test that output of 'jcmd' and 'jcmd -l' match a specific pattern
-
-JCMD="${TESTJAVA}/bin/jcmd"
-
-${JCMD} -J-XX:+UsePerfData 2>&1 | awk -f ${TESTSRC}/jcmd_Output1.awk
-
-${JCMD} -J-XX:+UsePerfData -l 2>&1 | awk -f ${TESTSRC}/jcmd_Output1.awk
diff --git a/test/sun/tools/jcmd/jcmd-big-script.sh b/test/sun/tools/jcmd/jcmd-big-script.sh
deleted file mode 100644
--- a/test/sun/tools/jcmd/jcmd-big-script.sh
+++ /dev/null
@@ -1,70 +0,0 @@
-#!/bin/sh
-
-#
-# Copyright (c) 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 7154822
-# @summary test if we can send a file over 1024 bytes large via jcmd -f
-# @author David Buck
-#
-# @library ../common
-# @build SimpleApplication ShutdownSimpleApplication
-# @run shell jcmd-big-script.sh
-
-. ${TESTSRC}/../common/CommonSetup.sh
-. ${TESTSRC}/../common/ApplicationSetup.sh
-
-# Start application and use PORTFILE for coordination
-PORTFILE="${TESTCLASSES}"/shutdown.port
-startApplication SimpleApplication "${PORTFILE}"
-
-failed=0;
-
-# -f <script>
-rm -f jcmd.out 2>/dev/null
-set +e # even if jcmd fails, we do not want abort the script yet.
-${JCMD} -J-XX:+UsePerfData $appJavaPid -f ${TESTSRC}/dcmd-big-script.txt > jcmd.out 2>&1
-status="$?"
-set -e
-if [ "$status" != 0 ]; then
-  echo "jcmd command returned non-zero exit code (status=$status). Failed."
-  failed=1;
-fi
-cat jcmd.out
-set +e # if the test passes, grep will "fail" with an exit code of 1
-grep Exception jcmd.out > /dev/null 2>&1
-status="$?"
-set -e
-if [ "$status" = 0 ]; then
-  echo "Output of \"jcmd [pid] -f dcmd-big-script.txt\" contains string \"Exception\". Failed."
-  failed=1;
-fi
-
-# clean up
-rm -f jcmd.out 2>/dev/null
-stopApplication "${PORTFILE}"
-waitForApplication
-
-exit $failed
diff --git a/test/sun/tools/jcmd/jcmd-f.sh b/test/sun/tools/jcmd/jcmd-f.sh
deleted file mode 100644
--- a/test/sun/tools/jcmd/jcmd-f.sh
+++ /dev/null
@@ -1,63 +0,0 @@
-#!/bin/sh
-
-#
-# Copyright (c) 2011, 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 7104647
-# @summary Unit test for jcmd utility
-#
-# @library ../common
-# @build SimpleApplication ShutdownSimpleApplication
-# @run shell jcmd-f.sh
-
-. ${TESTSRC}/../common/CommonSetup.sh
-. ${TESTSRC}/../common/ApplicationSetup.sh
-
-# Start application and use PORTFILE for coordination
-PORTFILE="${TESTCLASSES}"/shutdown.port
-startApplication SimpleApplication "${PORTFILE}"
-
-# all return statuses are checked in this test
-set +e
-
-failed=0
-
-# -f <script>
-rm -f jcmd.out 2>/dev/null
-${JCMD} -J-XX:+UsePerfData $appJavaPid -f ${TESTSRC}/dcmd-script.txt | awk '{ if (NR>1) print $0;}' > jcmd.out 2>&1
-echo jcmd.out
-diff -w jcmd.out ${TESTSRC}/help_help.out
-if [ $? != 0 ]; then
-  echo "Output of jcmd [pid] -f dcmd-script.txt  differ from expected output. Failed."
-  rm -f jcmd.out 2>/dev/null
-  failed=1;
-fi
-
-set -e
-
-stopApplication "${PORTFILE}"
-waitForApplication
-
-exit $failed
diff --git a/test/sun/tools/jcmd/jcmd-help-help.sh b/test/sun/tools/jcmd/jcmd-help-help.sh
deleted file mode 100644
--- a/test/sun/tools/jcmd/jcmd-help-help.sh
+++ /dev/null
@@ -1,63 +0,0 @@
-#!/bin/sh
-
-#
-# Copyright (c) 2011, 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 7104647
-# @summary Unit test for jcmd utility
-#
-# @library ../common
-# @build SimpleApplication ShutdownSimpleApplication
-# @run shell jcmd-help-help.sh
-
-. ${TESTSRC}/../common/CommonSetup.sh
-. ${TESTSRC}/../common/ApplicationSetup.sh
-
-# Start application and use PORTFILE for coordination
-PORTFILE="${TESTCLASSES}"/shutdown.port
-startApplication SimpleApplication "${PORTFILE}"
-
-# all return statuses are checked in this test
-set +e
-
-failed=0
-
-# help help
-rm -f jcmd.out 2>/dev/null
-${JCMD} -J-XX:+UsePerfData $appJavaPid help help | awk '{ if (NR>1) print $0;}' > jcmd.out 2>&1
-echo jcmd.out
-diff -w jcmd.out ${TESTSRC}/help_help.out
-if [ $? != 0 ]; then
-  echo "Output of jcmd [pid] help help differ from expected output. Failed."
-  rm -f jcmd.out 2>/dev/null
-  failed=1;
-fi
-
-set -e
-
-stopApplication "${PORTFILE}"
-waitForApplication
-
-exit $failed
diff --git a/test/sun/tools/jcmd/jcmd-help.sh b/test/sun/tools/jcmd/jcmd-help.sh
deleted file mode 100644
--- a/test/sun/tools/jcmd/jcmd-help.sh
+++ /dev/null
@@ -1,54 +0,0 @@
-#
-# Copyright (c) 2011, 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 7104647
-# @run shell jcmd-help.sh
-# @summary Test that output of 'jcmd -h' matches the usage.out file
-
-JCMD="${TESTJAVA}/bin/jcmd"
-
-rm -f jcmd.out 2>/dev/null
-${JCMD} -J-XX:+UsePerfData -h > jcmd.out 2>&1
-
-diff -w jcmd.out ${TESTSRC}/usage.out
-if [ $? != 0 ]
-then
-  echo "Output of jcmd -h differ from expected output. Failed."
-  rm -f jcmd.out 2>/dev/null
-  exit 1
-fi
-
-rm -f jcmd.out 2>/dev/null
-${JCMD} -J-XX:+UsePerfData -help > jcmd.out 2>&1
-
-diff -w jcmd.out ${TESTSRC}/usage.out
-if [ $? != 0 ]
-then
-  echo "Output of jcmd -help differ from expected output. Failed."
-  rm -f jcmd.out 2>/dev/null
-  exit 1
-fi
-
-rm -f jcmd.out 2>/dev/null
-exit 0
diff --git a/test/sun/tools/jcmd/jcmd-pid.sh b/test/sun/tools/jcmd/jcmd-pid.sh
deleted file mode 100644
--- a/test/sun/tools/jcmd/jcmd-pid.sh
+++ /dev/null
@@ -1,60 +0,0 @@
-#!/bin/sh
-
-#
-# Copyright (c) 2011, 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 7104647
-# @summary Unit test for jcmd utility
-#
-# @library ../common
-# @build SimpleApplication ShutdownSimpleApplication
-# @run shell jcmd-pid.sh
-
-. ${TESTSRC}/../common/CommonSetup.sh
-. ${TESTSRC}/../common/ApplicationSetup.sh
-
-# Start application and use PORTFILE for coordination
-PORTFILE="${TESTCLASSES}"/shutdown.port
-startApplication SimpleApplication "${PORTFILE}"
-
-# all return statuses are checked in this test
-set +e
-
-failed=0
-
-# help command 
-${JCMD} -J-XX:+UsePerfData $appJavaPid help 2>&1 | awk -f ${TESTSRC}/jcmd_pid_Output1.awk
-if [ $? != 0 ]; then failed=1; fi
-
-# PerfCounter.list option
-${JCMD} -J-XX:+UsePerfData $appJavaPid PerfCounter.print 2>&1 | awk -f ${TESTSRC}/jcmd_pid_Output2.awk
-if [ $? != 0 ]; then failed=1; fi
-
-set -e
-
-stopApplication "${PORTFILE}"
-waitForApplication
-
-exit $failed
diff --git a/test/sun/tools/jcmd/jcmd_Output1.awk b/test/sun/tools/jcmd/jcmd_Output1.awk
deleted file mode 100644
--- a/test/sun/tools/jcmd/jcmd_Output1.awk
+++ /dev/null
@@ -1,37 +0,0 @@
-#
-BEGIN	{
-            totallines=0; matched=0; current=0
-	}
-
-# match on a main class name followed by arbitrary arguments
-/^[0-9]+ [a-z|A-Z][a-z|A-Z|0-9|\.]*($| .*$)/	{
-	    current=1;
-	}
-
-# or match on a path name to a jar or war file followed by arbitraty arguments
-# - note, jar files ending with ".jar" is only a convention, not a requirement.
-#Theoretically, any valid file name could occur here.
-/^[0-9]+ .*\.(jar|war)($| .*$)/	{
-	    current=1;
-}
-
-# or match on the condition that the class name is not available
-/^[0-9]+ -- .*$/	{
-	    current=1;
-	}
-
-# or match an empty class name
-/^[0-9]+ $/	{
-	    current=1;
-	}
-
-	{ totallines++; matched+=current; current=0; print $0 }
-
-END	{
-	    if ((totallines > 0) && (matched == totallines)) {
-	        exit 0
-	    }
-	    else {
-	        exit 1
-	    }
-	}
diff --git a/test/sun/tools/jcmd/jcmd_pid_Output1.awk b/test/sun/tools/jcmd/jcmd_pid_Output1.awk
deleted file mode 100644
--- a/test/sun/tools/jcmd/jcmd_pid_Output1.awk
+++ /dev/null
@@ -1,58 +0,0 @@
-#
-
-# section 0 = [PID]:
-# section 1 = "The following commands are available:"
-# section 2 = <list of commands, one command per line>
-# section 3 = blank line
-# section 4 = "For more information about a specific command use 'help <command>'."
-
-BEGIN	{
-    totallines=0; matched=0; section=0;
-}
-
-# match the first line (PID of the JVM followed by ':')
-/^[0-9]+:/{
-    if(section==0) {
-	matched++;
-	section=1;
-    }
-}
-
-/^The following commands are available:$/{
-    if(section==1) {
-	matched++;
-	section=2;
-    }
-}
-
-# match a command name
-/^[a-z|A-Z][a-z|A-Z|0-9|\.|_]*$/{
-    if(section==2) {
-	matched++;
-    }
-}
-
-/^$/{
-    if(section==2) {
-	matched++;
-	section=4;
-    }
-}
-
-/^For more information about a specific command use 'help <command>'\.$/{
-    if(section==4) {
-	matched++;
-	section=5;
-    }
-}
-
-{ totallines++; print $0 }
-
-END {
-    if ((totallines > 0) && (matched == totallines)) {
-	exit 0
-    }
-    else {
-	exit 1
-    }
-}
diff --git a/test/sun/tools/jcmd/jcmd_pid_Output2.awk b/test/sun/tools/jcmd/jcmd_pid_Output2.awk
deleted file mode 100644
--- a/test/sun/tools/jcmd/jcmd_pid_Output2.awk
+++ /dev/null
@@ -1,25 +0,0 @@
-#
-BEGIN	{
-	    totallines=0; matched=0
-	}
-
-# match on counter name followed '=' and an arbitrary value
-/^[a-z|A-Z][a-z|A-Z|0-9|\.|_]*=.*$/	{
-	    matched++;
-	}
-
-# or match the first line (PID of the JVM followed by ':')
-/^[0-9]+:/	{
-	    matched++;
-	}
-
-	{ totallines++; print $0 }
-
-END	{
-    if ((totallines > 0) && (matched == totallines)) {
-	exit 0
-    }
-    else {
-	exit 1
-    }
-}
diff --git a/test/sun/tools/jcmd/usage.out b/test/sun/tools/jcmd/usage.out
--- a/test/sun/tools/jcmd/usage.out
+++ b/test/sun/tools/jcmd/usage.out
@@ -1,15 +1,15 @@
 Usage: jcmd <pid | main class> <command ...|PerfCounter.print|-f file>
-   or: jcmd -l                                                       
-   or: jcmd -h                                                       
+   or: jcmd -l                                                    
+   or: jcmd -h                                                    
                                                                   
-  command must be a valid jcmd command for the selected jvm.    
+  command must be a valid jcmd command for the selected jvm.      
   Use the command "help" to see which commands are available.   
   If the pid is 0, commands will be sent to all Java processes.   
   The main class argument will be used to match (either partially 
   or fully) the class used to start Java.                         
   If no options are given, lists Java processes (same as -p).     
                                                                   
-  PerfCounter.print display the counters exposed by this process   
+  PerfCounter.print display the counters exposed by this process  
   -f  read and execute commands from the file                     
   -l  list JVM processes on the local machine                     
   -h  this help                                                   

Reply via email to