8072931: JEP-JDK-8059557: Test task: test framework development
authorddmitriev
Fri, 19 Jun 2015 07:57:31 +0300
changeset 31372 9821df46cf47
parent 31371 311143309e73
child 31373 21f527ce09e0
8072931: JEP-JDK-8059557: Test task: test framework development Summary: Test set for JEP 245 Validate JVM Command-Line Flag Arguments Reviewed-by: ctornqvi, dholmes, gziemski
hotspot/test/TEST.groups
hotspot/test/runtime/CommandLine/OptionsValidation/TestJcmdOutput.java
hotspot/test/runtime/CommandLine/OptionsValidation/TestOptionsWithRanges.java
hotspot/test/runtime/CommandLine/OptionsValidation/TestOptionsWithRangesDynamic.java
hotspot/test/runtime/CommandLine/OptionsValidation/common/optionsvalidation/DoubleJVMOption.java
hotspot/test/runtime/CommandLine/OptionsValidation/common/optionsvalidation/IntJVMOption.java
hotspot/test/runtime/CommandLine/OptionsValidation/common/optionsvalidation/JVMOption.java
hotspot/test/runtime/CommandLine/OptionsValidation/common/optionsvalidation/JVMOptionsUtils.java
--- a/hotspot/test/TEST.groups	Thu Jun 18 14:39:38 2015 -0500
+++ b/hotspot/test/TEST.groups	Fri Jun 19 07:57:31 2015 +0300
@@ -420,6 +420,7 @@
  -runtime/SharedArchiveFile/DefaultUseWithClient.java \
  -runtime/Thread/CancellableThreadTest.java \
  -runtime/7158988/FieldMonitor.java \
+ -runtime/CommandLine/OptionsValidation/TestOptionsWithRanges.java \
   sanity/ \
   testlibrary_tests/TestMutuallyExclusivePlatformPredicates.java
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/CommandLine/OptionsValidation/TestJcmdOutput.java	Fri Jun 19 07:57:31 2015 +0300
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @summary Verify jcmd error message for out-of-range value and for
+ *          value which is not allowed by constraint. Also check that
+ *          jcmd does not print an error message to the target process output.
+ * @library /testlibrary
+ * @modules java.base/sun.misc
+ *          java.management
+ *          jdk.management
+ * @run main TestJcmdOutput
+ */
+
+import jdk.test.lib.Asserts;
+import jdk.test.lib.DynamicVMOption;
+import jdk.test.lib.OutputAnalyzer;
+import jdk.test.lib.ProcessTools;
+import jdk.test.lib.dcmd.PidJcmdExecutor;
+
+public class TestJcmdOutput {
+
+    /* Message printed by jcmd for value which is out-of-range */
+    static final String JCMD_OUT_OF_RANGE_MESSAGE = "error: must have value in range";
+    /* Message printed by jcmd for value which is not allowed by constraint */
+    static final String JCMD_CONSTRAINT_MESSAGE = "value violates its flag's constraint";
+
+    public static void main(String[] args) throws Exception {
+        OutputAnalyzer output;
+
+        System.out.println("Verify jcmd error message and that jcmd does not write errors to the target process output");
+        output = new OutputAnalyzer((ProcessTools.createJavaProcessBuilder(
+                "-Dtest.jdk=" + System.getProperty("test.jdk"),
+                "-XX:MinHeapFreeRatio=20", "-XX:MaxHeapFreeRatio=80", runJcmd.class.getName())).start());
+
+        output.shouldHaveExitValue(0);
+        /* Verify that jcmd not print error message to the target process output */
+        output.shouldNotContain(JCMD_OUT_OF_RANGE_MESSAGE);
+        output.shouldNotContain(JCMD_CONSTRAINT_MESSAGE);
+    }
+
+    public static class runJcmd {
+
+        public static void main(String[] args) throws Exception {
+            int minHeapFreeRatio = new Integer((new DynamicVMOption("MinHeapFreeRatio")).getValue());
+            int maxHeapFreeRatio = new Integer((new DynamicVMOption("MaxHeapFreeRatio")).getValue());
+            PidJcmdExecutor executor = new PidJcmdExecutor();
+
+            Asserts.assertGT(minHeapFreeRatio, 0, "MinHeapFreeRatio must be greater than 0");
+            Asserts.assertLT(maxHeapFreeRatio, 100, "MaxHeapFreeRatio must be less than 100");
+
+            /* Check out-of-range values */
+            executor.execute("VM.set_flag MinHeapFreeRatio -1", true).shouldContain(JCMD_OUT_OF_RANGE_MESSAGE);
+            executor.execute("VM.set_flag MaxHeapFreeRatio 101", true).shouldContain(JCMD_OUT_OF_RANGE_MESSAGE);
+
+            /* Check values which not allowed by constraint */
+            executor.execute(
+                    String.format("VM.set_flag MinHeapFreeRatio %d", maxHeapFreeRatio + 1), true)
+                    .shouldContain(JCMD_CONSTRAINT_MESSAGE);
+            executor.execute(
+                    String.format("VM.set_flag MaxHeapFreeRatio %d", minHeapFreeRatio - 1), true)
+                    .shouldContain(JCMD_CONSTRAINT_MESSAGE);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/CommandLine/OptionsValidation/TestOptionsWithRanges.java	Fri Jun 19 07:57:31 2015 +0300
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @summary Test VM Options with ranges
+ * @library /testlibrary /runtime/CommandLine/OptionsValidation/common
+ * @modules java.base/sun.misc
+ *          java.management
+ *          jdk.attach
+ *          jdk.management/sun.tools.attach
+ * @run main/othervm/timeout=600 TestOptionsWithRanges
+ */
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import jdk.test.lib.Asserts;
+import optionsvalidation.JVMOption;
+import optionsvalidation.JVMOptionsUtils;
+
+public class TestOptionsWithRanges {
+
+    public static void main(String[] args) throws Exception {
+        int failedTests;
+        Map<String, JVMOption> allOptionsAsMap = JVMOptionsUtils.getOptionsWithRangeAsMap();
+        List<JVMOption> allOptions;
+
+        /*
+         * Remove CICompilerCount from testing because currently it can hang system
+         */
+        allOptionsAsMap.remove("CICompilerCount");
+
+        allOptions = new ArrayList<>(allOptionsAsMap.values());
+
+        Asserts.assertGT(allOptions.size(), 0, "Options with ranges not found!");
+
+        System.out.println("Parsed " + allOptions.size() + " options with ranges. Start test!");
+
+        failedTests = JVMOptionsUtils.runCommandLineTests(allOptions);
+
+        Asserts.assertEQ(failedTests, 0,
+                String.format("%d tests failed! %s", failedTests, JVMOptionsUtils.getMessageWithFailures()));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/CommandLine/OptionsValidation/TestOptionsWithRangesDynamic.java	Fri Jun 19 07:57:31 2015 +0300
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @summary Test writeable VM Options with ranges.
+ * @library /testlibrary /runtime/CommandLine/OptionsValidation/common
+ * @modules java.base/sun.misc
+ *          java.management
+ *          jdk.attach
+ *          jdk.management/sun.tools.attach
+ * @run main/othervm -XX:MinHeapFreeRatio=0 -XX:MaxHeapFreeRatio=100 TestOptionsWithRangesDynamic
+ */
+
+import java.util.List;
+import jdk.test.lib.Asserts;
+import optionsvalidation.JVMOption;
+import optionsvalidation.JVMOptionsUtils;
+
+public class TestOptionsWithRangesDynamic {
+
+    public static void main(String[] args) throws Exception {
+        int failedTests;
+        List<JVMOption> allWriteableOptions;
+
+        /* Get only writeable options */
+        allWriteableOptions = JVMOptionsUtils.getOptionsWithRange(origin -> (origin.contains("manageable") || origin.contains("rw")));
+
+        Asserts.assertGT(allWriteableOptions.size(), 0, "Options with ranges not found!");
+
+        System.out.println("Test " + allWriteableOptions.size() + " writeable options with ranges. Start test!");
+
+        failedTests = JVMOptionsUtils.runDynamicTests(allWriteableOptions);
+
+        failedTests += JVMOptionsUtils.runJcmdTests(allWriteableOptions);
+
+        failedTests += JVMOptionsUtils.runAttachTests(allWriteableOptions);
+
+        Asserts.assertEQ(failedTests, 0,
+                String.format("%d tests failed! %s", failedTests, JVMOptionsUtils.getMessageWithFailures()));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/CommandLine/OptionsValidation/common/optionsvalidation/DoubleJVMOption.java	Fri Jun 19 07:57:31 2015 +0300
@@ -0,0 +1,202 @@
+/*
+ * Copyright (c) 2015, 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 optionsvalidation;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class DoubleJVMOption extends JVMOption {
+
+    /**
+     * Additional double values to test
+     */
+    private static final double ADDITIONAL_TEST_DOUBLE_NEGATIVE = -1.5;
+    private static final double ADDITIONAL_TEST_DOUBLE_ZERO = 0.0;
+    private static final double ADDITIONAL_TEST_DOUBLE_POSITIVE = 1.75;
+
+    /**
+     * Mininum option value
+     */
+    private double min;
+    /**
+     * Maximum option value
+     */
+    private double max;
+
+    /**
+     * Initialize double option with passed name
+     *
+     * @param name name of the option
+     */
+    DoubleJVMOption(String name) {
+        this.name = name;
+        min = Double.MIN_VALUE;
+        max = Double.MAX_VALUE;
+    }
+
+    /**
+     * Initialize double option with passed name, min and max values
+     *
+     * @param name name of the option
+     * @param min minimum value of the option
+     * @param max maximum value of the option
+     */
+    public DoubleJVMOption(String name, double min, double max) {
+        this(name);
+        this.min = min;
+        this.max = max;
+    }
+
+    /**
+     * Set new minimum option value
+     *
+     * @param min new minimum value
+     */
+    @Override
+    void setMin(String min) {
+        this.min = new Double(min);
+    }
+
+    /**
+     * Get string with minimum value of the option
+     *
+     * @return string with minimum value of the option
+     */
+    @Override
+    String getMin() {
+        return formatValue(min);
+    }
+
+    /**
+     * Set new maximum option value
+     *
+     * @param max new maximum value
+     */
+    @Override
+    void setMax(String max) {
+        this.max = new Double(max);
+    }
+
+    /**
+     * Get string with maximum value of the option
+     *
+     * @return string with maximum value of the option
+     */
+    @Override
+    String getMax() {
+        return formatValue(max);
+    }
+
+    private String formatValue(double value) {
+        return String.format("%f", value);
+    }
+
+    /**
+     * Return list of strings with valid option values which used for testing
+     * using jcmd, attach and etc.
+     *
+     * @return list of strings which contain valid values for option
+     */
+    @Override
+    protected List<String> getValidValues() {
+        List<String> validValues = new ArrayList<>();
+
+        validValues.add(formatValue(min));
+        validValues.add(formatValue(max));
+
+        if ((Double.compare(min, ADDITIONAL_TEST_DOUBLE_NEGATIVE) < 0)
+                && (Double.compare(max, ADDITIONAL_TEST_DOUBLE_NEGATIVE) > 0)) {
+            validValues.add(formatValue(ADDITIONAL_TEST_DOUBLE_NEGATIVE));
+        }
+
+        if ((Double.compare(min, ADDITIONAL_TEST_DOUBLE_ZERO) < 0)
+                && (Double.compare(max, ADDITIONAL_TEST_DOUBLE_ZERO) > 0)) {
+            validValues.add(formatValue(ADDITIONAL_TEST_DOUBLE_ZERO));
+        }
+
+        if ((Double.compare(min, ADDITIONAL_TEST_DOUBLE_POSITIVE) < 0)
+                && (Double.compare(max, ADDITIONAL_TEST_DOUBLE_POSITIVE) > 0)) {
+            validValues.add(formatValue(ADDITIONAL_TEST_DOUBLE_POSITIVE));
+        }
+
+        return validValues;
+    }
+
+    /**
+     * Return list of strings with invalid option values which used for testing
+     * using jcmd, attach and etc.
+     *
+     * @return list of strings which contain invalid values for option
+     */
+    @Override
+    protected List<String> getInvalidValues() {
+        List<String> invalidValues = new ArrayList<>();
+
+        if (withRange) {
+            /* Return invalid values only for options which have defined range in VM */
+            if (Double.compare(min, Double.MIN_VALUE) != 0) {
+                if ((Double.compare(min, 0.0) > 0)
+                        && (Double.isNaN(min * 0.999) == false)) {
+                    invalidValues.add(formatValue(min * 0.999));
+                } else if ((Double.compare(min, 0.0) < 0)
+                        && (Double.isNaN(min * 1.001) == false)) {
+                    invalidValues.add(formatValue(min * 1.001));
+                }
+            }
+
+            if (Double.compare(max, Double.MAX_VALUE) != 0) {
+                if ((Double.compare(max, 0.0) > 0)
+                        && (Double.isNaN(max * 1.001) == false)) {
+                    invalidValues.add(formatValue(max * 1.001));
+                } else if ((Double.compare(max, 0.0) < 0)
+                        && (Double.isNaN(max * 0.999) == false)) {
+                    invalidValues.add(formatValue(max * 0.999));
+                }
+            }
+        }
+
+        return invalidValues;
+    }
+
+    /**
+     * Return expected error message for option with value "value" when it used
+     * on command line with passed value
+     *
+     * @param value option value
+     * @return expected error message
+     */
+    @Override
+    protected String getErrorMessageCommandLine(String value) {
+        String errorMsg;
+
+        if (withRange) {
+            /* Option have defined range in VM */
+            errorMsg = "is outside the allowed range";
+        } else {
+            errorMsg = "";
+        }
+
+        return errorMsg;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/CommandLine/OptionsValidation/common/optionsvalidation/IntJVMOption.java	Fri Jun 19 07:57:31 2015 +0300
@@ -0,0 +1,309 @@
+/*
+ * Copyright (c) 2015, 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 optionsvalidation;
+
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.List;
+import jdk.test.lib.Platform;
+
+public class IntJVMOption extends JVMOption {
+
+    private static final BigInteger MIN_LONG;
+    private static final BigInteger MAX_LONG;
+    private static final BigInteger MAX_UNSIGNED_LONG;
+    private static final BigInteger MAX_UNSIGNED_LONG_64;
+    private static final BigInteger MINUS_ONE = new BigInteger("-1");
+    private static final BigInteger TWO = new BigInteger("2");
+    private static final BigInteger MIN_4_BYTE_INT = new BigInteger("-2147483648");
+    private static final BigInteger MAX_4_BYTE_INT = new BigInteger("2147483647");
+    private static final BigInteger MAX_4_BYTE_INT_PLUS_ONE = new BigInteger("2147483648");
+    private static final BigInteger MAX_4_BYTE_UNSIGNED_INT = new BigInteger("4294967295");
+    private static final BigInteger MAX_4_BYTE_UNSIGNED_INT_PLUS_ONE = new BigInteger("4294967296");
+
+    /**
+     * Mininum option value
+     */
+    private BigInteger min;
+
+    /**
+     * Maximum option value
+     */
+    private BigInteger max;
+
+    /**
+     * Option type: intx, uintx, size_t or uint64_t
+     */
+    private String type;
+
+    /**
+     * Is this value signed or unsigned
+     */
+    private boolean unsigned;
+
+    /**
+     * Is this 32 bit type
+     */
+    private boolean is32Bit = false;
+
+    /**
+     * Is this value 64 bit unsigned
+     */
+    private boolean uint64 = false;
+
+    static {
+        if (Platform.is32bit()) {
+            MIN_LONG = new BigInteger(String.valueOf(Integer.MIN_VALUE));
+            MAX_LONG = new BigInteger(String.valueOf(Integer.MAX_VALUE));
+            MAX_UNSIGNED_LONG = MAX_LONG.multiply(TWO).add(BigInteger.ONE);
+        } else {
+            MIN_LONG = new BigInteger(String.valueOf(Long.MIN_VALUE));
+            MAX_LONG = new BigInteger(String.valueOf(Long.MAX_VALUE));
+            MAX_UNSIGNED_LONG = MAX_LONG.multiply(TWO).add(BigInteger.ONE);
+        }
+
+        MAX_UNSIGNED_LONG_64 = (new BigInteger(String.valueOf(Long.MAX_VALUE)))
+                .multiply(TWO).add(BigInteger.ONE);
+    }
+
+    private IntJVMOption() {
+        type = "";
+    }
+
+    /**
+     * Initialize new integer option with given type. Type can be: INTX -
+     * integer signed option UINTX - unsigned integer option UINT64_T - unsigned
+     * 64 bit integer option
+     *
+     * @param name name of the option
+     * @param type type of the option
+     */
+    IntJVMOption(String name, String type) {
+        this.name = name;
+        this.type = type;
+
+        switch (type) {
+            case "uint64_t":
+                unsigned = true;
+                uint64 = true;
+                max = MAX_UNSIGNED_LONG_64;
+                break;
+            case "uintx":
+            case "size_t":
+                unsigned = true;
+                max = MAX_UNSIGNED_LONG;
+                break;
+            case "uint":
+                unsigned = true;
+                is32Bit = true;
+                max = MAX_4_BYTE_UNSIGNED_INT;
+                break;
+            case "int":
+                min = MIN_4_BYTE_INT;
+                max = MAX_4_BYTE_INT;
+                is32Bit = true;
+                break;
+            default:
+                min = MIN_LONG;
+                max = MAX_LONG;
+                break;
+        }
+
+        if (unsigned) {
+            min = BigInteger.ZERO;
+        }
+    }
+
+    /**
+     * Initialize integer option with passed name, min and max values. Min and
+     * max are string because they can be very big, bigger than long.
+     *
+     * @param name name of the option
+     * @param min minimum value of the option
+     * @param max maximum value of the option
+     */
+    public IntJVMOption(String name, String min, String max) {
+        this();
+        this.name = name;
+        this.min = new BigInteger(min);
+        this.max = new BigInteger(max);
+    }
+
+    /**
+     * Set new minimum option value
+     *
+     * @param min new minimum value
+     */
+    @Override
+    void setMin(String min) {
+        this.min = new BigInteger(min);
+    }
+
+    /**
+     * Get string with minimum value of the option
+     *
+     * @return string with minimum value of the option
+     */
+    @Override
+    String getMin() {
+        return min.toString();
+    }
+
+    /**
+     * Set new maximum option value
+     *
+     * @param max new maximum value
+     */
+    @Override
+    void setMax(String max) {
+        this.max = new BigInteger(max);
+    }
+
+    /**
+     * Get string with maximum value of the option
+     *
+     * @return string with maximum value of the option
+     */
+    @Override
+    String getMax() {
+        return max.toString();
+    }
+
+    /**
+     * Return list of strings with valid option values which used for testing
+     * using jcmd, attach and etc.
+     *
+     * @return list of strings which contain valid values for option
+     */
+    @Override
+    protected List<String> getValidValues() {
+        List<String> validValues = new ArrayList<>();
+
+        validValues.add(min.toString());
+        validValues.add(max.toString());
+
+        if ((min.compareTo(MINUS_ONE) == -1) && (max.compareTo(MINUS_ONE) == 1)) {
+            /*
+             * Add -1 as valid value if min is less than -1 and max is greater than -1
+             */
+            validValues.add("-1");
+        }
+
+        if ((min.compareTo(BigInteger.ZERO) == -1) && (max.compareTo(BigInteger.ZERO) == 1)) {
+            /*
+             * Add 0 as valid value if min is less than 0 and max is greater than 0
+             */
+            validValues.add("0");
+        }
+        if ((min.compareTo(BigInteger.ONE) == -1) && (max.compareTo(BigInteger.ONE) == 1)) {
+            /*
+             * Add 1 as valid value if min is less than 1 and max is greater than 1
+             */
+            validValues.add("1");
+        }
+
+        if (max.compareTo(MAX_4_BYTE_INT_PLUS_ONE) == 1) {
+            /*
+             * Check for overflow when flag is assigned to the
+             * 4 byte int variable
+             */
+            validValues.add(MAX_4_BYTE_INT_PLUS_ONE.toString());
+        }
+
+        if (max.compareTo(MAX_4_BYTE_UNSIGNED_INT_PLUS_ONE) == 1) {
+            /*
+             * Check for overflow when flag is assigned to the
+             * 4 byte unsigned int variable
+             */
+            validValues.add(MAX_4_BYTE_UNSIGNED_INT_PLUS_ONE.toString());
+        }
+
+        return validValues;
+    }
+
+    /**
+     * Return list of strings with invalid option values which used for testing
+     * using jcmd, attach and etc.
+     *
+     * @return list of strings which contain invalid values for option
+     */
+    @Override
+    protected List<String> getInvalidValues() {
+        List<String> invalidValues = new ArrayList<>();
+
+        if (withRange) {
+            /* Return invalid values only for options which have defined range in VM */
+            if ((is32Bit && min.compareTo(MIN_4_BYTE_INT) != 0)
+                    || (!is32Bit && min.compareTo(MIN_LONG) != 0)) {
+                invalidValues.add(min.subtract(BigInteger.ONE).toString());
+            }
+
+            if (!unsigned
+                    && ((is32Bit && (max.compareTo(MAX_4_BYTE_INT) != 0))
+                    || (!is32Bit && (max.compareTo(MAX_LONG) != 0)))) {
+                invalidValues.add(max.add(BigInteger.ONE).toString());
+            }
+
+            if (unsigned
+                    && ((is32Bit && (max.compareTo(MAX_4_BYTE_UNSIGNED_INT) != 0))
+                    || (!is32Bit && !uint64 && (max.compareTo(MAX_UNSIGNED_LONG) != 0))
+                    || (uint64 && (max.compareTo(MAX_UNSIGNED_LONG_64) != 0)))) {
+                invalidValues.add(max.add(BigInteger.ONE).toString());
+            }
+        }
+
+        return invalidValues;
+    }
+
+    /**
+     * Return expected error message for option with value "value" when it used
+     * on command line with passed value
+     *
+     * @param value Option value
+     * @return expected error message
+     */
+    @Override
+    protected String getErrorMessageCommandLine(String value) {
+        String errorMsg;
+
+        if (withRange) {
+            /* Option have defined range in VM */
+            if (unsigned && ((new BigInteger(value)).compareTo(BigInteger.ZERO) < 0)) {
+                /*
+                 * Special case for unsigned options with lower range equal to 0. If
+                 * passed value is negative then error will be caught earlier for
+                 * such options. Thus use different error message.
+                 */
+                errorMsg = String.format("Improperly specified VM option '%s=%s'", name, value);
+            } else {
+                errorMsg = String.format("%s %s=%s is outside the allowed range [ %s ... %s ]",
+                        type, name, value, min.toString(), max.toString());
+            }
+        } else {
+            errorMsg = "";
+        }
+
+        return errorMsg;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/CommandLine/OptionsValidation/common/optionsvalidation/JVMOption.java	Fri Jun 19 07:57:31 2015 +0300
@@ -0,0 +1,477 @@
+/*
+ * Copyright (c) 2015, 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 optionsvalidation;
+
+import com.sun.tools.attach.VirtualMachine;
+import com.sun.tools.attach.AttachOperationFailedException;
+import java.util.ArrayList;
+import java.util.List;
+import jdk.test.lib.DynamicVMOption;
+import jdk.test.lib.OutputAnalyzer;
+import jdk.test.lib.ProcessTools;
+import jdk.test.lib.dcmd.CommandExecutor;
+import jdk.test.lib.dcmd.JMXExecutor;
+import sun.tools.attach.HotSpotVirtualMachine;
+
+import static optionsvalidation.JVMOptionsUtils.failedMessage;
+import static optionsvalidation.JVMOptionsUtils.printOutputContent;
+import static optionsvalidation.JVMOptionsUtils.VMType;
+
+public abstract class JVMOption {
+
+    /**
+     * Executor for JCMD
+     */
+    private final static CommandExecutor executor = new JMXExecutor();
+
+    /**
+     * Name of the tested parameter
+     */
+    protected String name;
+
+    /**
+     * Range is defined for option inside VM
+     */
+    protected boolean withRange;
+
+    /**
+     * Prepend string which added before testing option to the command line
+     */
+    private final List<String> prepend;
+    private final StringBuilder prependString;
+
+    protected JVMOption() {
+        this.prepend = new ArrayList<>();
+        prependString = new StringBuilder();
+        withRange = false;
+    }
+
+    /**
+     * Create JVM Option with given type and name.
+     *
+     * @param type type: "intx", "size_t", "uintx", "uint64_t" or "double"
+     * @param name name of the option
+     * @return created JVMOption
+     */
+    static JVMOption createVMOption(String type, String name) {
+        JVMOption parameter;
+
+        switch (type) {
+            case "int":
+            case "intx":
+            case "size_t":
+            case "uint":
+            case "uintx":
+            case "uint64_t":
+                parameter = new IntJVMOption(name, type);
+                break;
+            case "double":
+                parameter = new DoubleJVMOption(name);
+                break;
+            default:
+                throw new Error("Expected only \"int\", \"intx\", \"size_t\", "
+                        + "\"uint\", \"uintx\", \"uint64_t\", or \"double\" "
+                        + "option types! Got " + type + " type!");
+        }
+
+        return parameter;
+    }
+
+    /**
+     * Add passed options to the prepend options of the option. Prepend options
+     * will be added before testing option to the command line.
+     *
+     * @param options array of prepend options
+     */
+    public final void addPrepend(String... options) {
+        String toAdd;
+
+        for (String option : options) {
+            if (option.startsWith("-")) {
+                toAdd = option;
+            } else {
+                /* Add "-" before parameter name */
+                toAdd = "-" + option;
+
+            }
+            prepend.add(toAdd);
+            prependString.append(toAdd).append(" ");
+        }
+    }
+
+    /**
+     * Get name of the option
+     *
+     * @return name of the option
+     */
+    final String getName() {
+        return name;
+    }
+
+    /**
+     * Mark this option as option which range is defined inside VM
+     */
+    final void optionWithRange() {
+        withRange = true;
+    }
+
+    /**
+     * Set new minimum option value
+     *
+     * @param min new minimum value
+     */
+    abstract void setMin(String min);
+
+    /**
+     * Get string with minimum value of the option
+     *
+     * @return string with minimum value of the option
+     */
+    abstract String getMin();
+
+    /**
+     * Set new maximum option value
+     *
+     * @param max new maximum value
+     */
+    abstract void setMax(String min);
+
+    /**
+     * Get string with maximum value of the option
+     *
+     * @return string with maximum value of the option
+     */
+    abstract String getMax();
+
+    /**
+     * Return list of strings with valid option values which used for testing
+     * using jcmd, attach and etc.
+     *
+     * @return list of strings which contain valid values for option
+     */
+    protected abstract List<String> getValidValues();
+
+    /**
+     * Return list of strings with invalid option values which used for testing
+     * using jcmd, attach and etc.
+     *
+     * @return list of strings which contain invalid values for option
+     */
+    protected abstract List<String> getInvalidValues();
+
+    /**
+     * Return expected error message for option with value "value" when it used
+     * on command line with passed value
+     *
+     * @param value option value
+     * @return expected error message
+     */
+    protected abstract String getErrorMessageCommandLine(String value);
+
+    /**
+     * Testing writeable option using DynamicVMOption isValidValue and
+     * isInvalidValue methods
+     *
+     * @return number of failed tests
+     */
+    public int testDynamic() {
+        DynamicVMOption option = new DynamicVMOption(name);
+        int failedTests = 0;
+        String origValue;
+
+        if (option.isWriteable()) {
+
+            System.out.println("Testing " + name + " option dynamically by DynamicVMOption");
+
+            origValue = option.getValue();
+
+            for (String value : getValidValues()) {
+                if (!option.isValidValue(value)) {
+                    failedMessage(String.format("Option %s: Valid value \"%s\" is invalid", name, value));
+                    failedTests++;
+                }
+            }
+
+            for (String value : getInvalidValues()) {
+                if (option.isValidValue(value)) {
+                    failedMessage(String.format("Option %s: Invalid value \"%s\" is valid", name, value));
+                    failedTests++;
+                }
+            }
+
+            option.setValue(origValue);
+        }
+
+        return failedTests;
+    }
+
+    /**
+     * Testing writeable option using Jcmd
+     *
+     * @return number of failed tests
+     */
+    public int testJcmd() {
+        DynamicVMOption option = new DynamicVMOption(name);
+        int failedTests = 0;
+        OutputAnalyzer out;
+        String origValue;
+
+        if (option.isWriteable()) {
+
+            System.out.println("Testing " + name + " option dynamically by jcmd");
+
+            origValue = option.getValue();
+
+            for (String value : getValidValues()) {
+                out = executor.execute(String.format("VM.set_flag %s %s", name, value), true);
+
+                if (out.getOutput().contains(name + " error")) {
+                    failedMessage(String.format("Option %s: Can not change "
+                            + "option to valid value \"%s\" via jcmd", name, value));
+                    printOutputContent(out);
+                    failedTests++;
+                }
+            }
+
+            for (String value : getInvalidValues()) {
+                out = executor.execute(String.format("VM.set_flag %s %s", name, value), true);
+
+                if (!out.getOutput().contains(name + " error")) {
+                    failedMessage(String.format("Option %s: Error not reported for "
+                            + "option when it chagned to invalid value \"%s\" via jcmd", name, value));
+                    printOutputContent(out);
+                    failedTests++;
+                }
+            }
+
+            option.setValue(origValue);
+        }
+
+        return failedTests;
+    }
+
+    private boolean setFlagAttach(HotSpotVirtualMachine vm, String flagName, String flagValue) throws Exception {
+        boolean result;
+
+        try {
+            vm.setFlag(flagName, flagValue);
+            result = true;
+        } catch (AttachOperationFailedException e) {
+            result = false;
+        }
+
+        return result;
+    }
+
+    /**
+     * Testing writeable option using attach method
+     *
+     * @return number of failed tests
+     * @throws Exception if an error occurred while attaching to the target JVM
+     */
+    public int testAttach() throws Exception {
+        DynamicVMOption option = new DynamicVMOption(name);
+        int failedTests = 0;
+        String origValue;
+
+        if (option.isWriteable()) {
+
+            System.out.println("Testing " + name + " option dynamically via attach");
+
+            origValue = option.getValue();
+
+            HotSpotVirtualMachine vm = (HotSpotVirtualMachine) VirtualMachine.attach(String.valueOf(ProcessTools.getProcessId()));
+
+            for (String value : getValidValues()) {
+                if (!setFlagAttach(vm, name, value)) {
+                    failedMessage(String.format("Option %s: Can not change option to valid value \"%s\" via attach", name, value));
+                    failedTests++;
+                }
+            }
+
+            for (String value : getInvalidValues()) {
+                if (setFlagAttach(vm, name, value)) {
+                    failedMessage(String.format("Option %s: Option changed to invalid value \"%s\" via attach", name, value));
+                    failedTests++;
+                }
+            }
+
+            vm.detach();
+
+            option.setValue(origValue);
+        }
+
+        return failedTests;
+    }
+
+    /**
+     * Run java with passed parameter and check the result depending on the
+     * 'valid' parameter
+     *
+     * @param param tested parameter passed to the JVM
+     * @param valid indicates whether the JVM should fail or not
+     * @return true - if test passed
+     * @throws Exception if java process can not be started
+     */
+    private boolean runJavaWithParam(String optionValue, boolean valid) throws Exception {
+        int exitCode;
+        boolean result = true;
+        String value = optionValue.substring(optionValue.lastIndexOf("=") + 1);
+        String fullOptionString = prependString.toString() + optionValue;
+        List<String> runJava = new ArrayList<>();
+        OutputAnalyzer out;
+
+        if (VMType != null) {
+            runJava.add(VMType);
+        }
+        runJava.addAll(prepend);
+        runJava.add(optionValue);
+        runJava.add(JVMOptionsUtils.class.getName());
+
+        out = new OutputAnalyzer(ProcessTools.createJavaProcessBuilder(runJava.toArray(new String[0])).start());
+
+        exitCode = out.getExitValue();
+
+        if (out.getOutput().contains("A fatal error has been detected by the Java Runtime Environment")) {
+            /* Always consider "fatal error" in output as fail */
+            failedMessage(name, fullOptionString, valid, "JVM output reports a fatal error. JVM exited with code " + exitCode + "!");
+            printOutputContent(out);
+            result = false;
+        } else if (valid == true) {
+            if ((exitCode != 0) && (exitCode != 1)) {
+                failedMessage(name, fullOptionString, valid, "JVM exited with unexpected error code = " + exitCode);
+                printOutputContent(out);
+                result = false;
+            } else if ((exitCode == 1) && (out.getOutput().isEmpty() == true)) {
+                failedMessage(name, fullOptionString, valid, "JVM exited with error(exitcode == 1)"
+                        + ", but with empty stdout and stderr. Description of error is needed!");
+                result = false;
+            } else if (out.getOutput().contains("is outside the allowed range")) {
+                failedMessage(name, fullOptionString, valid, "JVM output contains \"is outside the allowed range\"");
+                printOutputContent(out);
+                result = false;
+            }
+        } else {
+            // valid == false
+            if (exitCode == 0) {
+                failedMessage(name, fullOptionString, valid, "JVM successfully exit");
+                result = false;
+            } else if (exitCode != 1) {
+                failedMessage(name, fullOptionString, valid, "JVM exited with code "
+                        + exitCode + " which not equal to 1");
+                result = false;
+            } else if (!out.getOutput().contains(getErrorMessageCommandLine(value))) {
+                failedMessage(name, fullOptionString, valid, "JVM output does not contain "
+                        + "expected output \"" + getErrorMessageCommandLine(value) + "\"");
+                printOutputContent(out);
+                result = false;
+            }
+        }
+
+        System.out.println("");
+
+        return result;
+    }
+
+    /**
+     * Construct option string with passed value
+     *
+     * @param value parameter value
+     * @return string containing option with passed value
+     */
+    private String constructOption(String value) {
+        return "-XX:" + name + "=" + value;
+    }
+
+    /**
+     * Return list of strings which contain options with valid values which can
+     * be used for testing on command line
+     *
+     * @return list of strings which contain options with valid values
+     */
+    private List<String> getValidCommandLineOptions() {
+        List<String> validParameters = new ArrayList<>();
+
+        for (String value : getValidValues()) {
+            validParameters.add(constructOption(value));
+        }
+
+        return validParameters;
+    }
+
+    /**
+     * Return list of strings which contain options with invalid values which
+     * can be used for testing on command line
+     *
+     * @return list of strings which contain options with invalid values
+     */
+    private List<String> getInvalidCommandLineOptions() {
+        List<String> invalidParameters = new ArrayList<>();
+
+        for (String value : getInvalidValues()) {
+            invalidParameters.add(constructOption(value));
+        }
+
+        return invalidParameters;
+    }
+
+    /**
+     * Perform test of the parameter. Call java with valid option values and
+     * with invalid option values.
+     *
+     * @return number of failed tests
+     * @throws Exception if java process can not be started
+     */
+    public int testCommandLine() throws Exception {
+        ProcessBuilder pb;
+        int failed = 0;
+        List<String> optionValuesList;
+
+        optionValuesList = getValidCommandLineOptions();
+
+        if (optionValuesList.isEmpty() != true) {
+            System.out.println("Testing valid " + name + " values.");
+            for (String optionValid : optionValuesList) {
+                if (runJavaWithParam(optionValid, true) == false) {
+                    failed++;
+                }
+            }
+        }
+
+        optionValuesList = getInvalidCommandLineOptions();
+
+        if (optionValuesList.isEmpty() != true) {
+            System.out.println("Testing invalid " + name + " values.");
+
+            for (String optionInvalid : optionValuesList) {
+                if (runJavaWithParam(optionInvalid, false) == false) {
+                    failed++;
+                }
+            }
+        }
+
+        /* return number of failed tests for this option */
+        return failed;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/CommandLine/OptionsValidation/common/optionsvalidation/JVMOptionsUtils.java	Fri Jun 19 07:57:31 2015 +0300
@@ -0,0 +1,450 @@
+/*
+ * Copyright (c) 2015, 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 optionsvalidation;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.StringTokenizer;
+import java.util.function.Predicate;
+import jdk.test.lib.OutputAnalyzer;
+import jdk.test.lib.Platform;
+import jdk.test.lib.ProcessTools;
+
+public class JVMOptionsUtils {
+
+    /* Java option which print options with ranges */
+    private static final String PRINT_FLAGS_RANGES = "-XX:+PrintFlagsRanges";
+
+    /* StringBuilder to accumulate failed message */
+    private static final StringBuilder finalFailedMessage = new StringBuilder();
+
+    /* Used to start the JVM with the same type as current */
+    static String VMType;
+
+    static {
+        if (Platform.isServer()) {
+            VMType = "-server";
+        } else if (Platform.isClient()) {
+            VMType = "-client";
+        } else if (Platform.isMinimal()) {
+            VMType = "-minimal";
+        } else if (Platform.isGraal()) {
+            VMType = "-graal";
+        } else {
+            VMType = null;
+        }
+    }
+
+    /**
+     * Add dependency for option depending on it's name. E.g. enable G1 GC for
+     * G1 options or add prepend options to not hit constraints.
+     *
+     * @param option option
+     */
+    private static void addNameDependency(JVMOption option) {
+        String name = option.getName();
+
+        if (name.startsWith("G1")) {
+            option.addPrepend("-XX:+UseG1GC");
+        }
+
+        if (name.startsWith("CMS")) {
+            option.addPrepend("-XX:+UseConcMarkSweepGC");
+        }
+
+        switch (name) {
+            case "MinHeapFreeRatio":
+                option.addPrepend("-XX:MaxHeapFreeRatio=100");
+                break;
+            case "MaxHeapFreeRatio":
+                option.addPrepend("-XX:MinHeapFreeRatio=0");
+                break;
+            case "MinMetaspaceFreeRatio":
+                option.addPrepend("-XX:MaxMetaspaceFreeRatio=100");
+                break;
+            case "MaxMetaspaceFreeRatio":
+                option.addPrepend("-XX:MinMetaspaceFreeRatio=0");
+                break;
+            case "CMSOldPLABMin":
+                option.addPrepend("-XX:CMSOldPLABMax=" + option.getMax());
+                break;
+            case "CMSOldPLABMax":
+                option.addPrepend("-XX:CMSOldPLABMin=" + option.getMin());
+                break;
+            case "CMSPrecleanNumerator":
+                option.addPrepend("-XX:CMSPrecleanDenominator=" + option.getMax());
+                break;
+            case "CMSPrecleanDenominator":
+                option.addPrepend("-XX:CMSPrecleanNumerator=" + ((new Integer(option.getMin())) - 1));
+                break;
+            case "InitialTenuringThreshold":
+                option.addPrepend("-XX:MaxTenuringThreshold=" + option.getMax());
+                break;
+            default:
+                /* Do nothing */
+                break;
+        }
+
+    }
+
+    /**
+     * Add dependency for option depending on it's type. E.g. run the JVM in
+     * compilation mode for compiler options.
+     *
+     * @param option option
+     * @param type type of the option
+     */
+    private static void addTypeDependency(JVMOption option, String type) {
+        if (type.contains("C1") || type.contains("C2")) {
+            /* Run in compiler mode for compiler flags */
+            option.addPrepend("-Xcomp");
+        }
+    }
+
+    /**
+     * Parse JVM Options. Get input from "inputReader". Parse using
+     * "-XX:+PrintFlagsRanges" output format.
+     *
+     * @param inputReader input data for parsing
+     * @param withRanges true if needed options with defined ranges inside JVM
+     * @param acceptOrigin predicate for option origins. Origins can be
+     * "product", "diagnostic" etc. Accept option only if acceptOrigin evaluates
+     * to true.
+     * @return map from option name to the JVMOption object
+     * @throws IOException if an error occurred while reading the data
+     */
+    private static Map<String, JVMOption> getJVMOptions(Reader inputReader,
+            boolean withRanges, Predicate<String> acceptOrigin) throws IOException {
+        BufferedReader reader = new BufferedReader(inputReader);
+        String type;
+        String line;
+        String token;
+        String name;
+        StringTokenizer st;
+        JVMOption option;
+        Map<String, JVMOption> allOptions = new LinkedHashMap<>();
+
+        // Skip first line
+        line = reader.readLine();
+
+        while ((line = reader.readLine()) != null) {
+            /*
+             * Parse option from following line:
+             * <type> <name> [ <min, optional> ... <max, optional> ] {<origin>}
+             */
+            st = new StringTokenizer(line);
+
+            type = st.nextToken();
+
+            name = st.nextToken();
+
+            option = JVMOption.createVMOption(type, name);
+
+            /* Skip '[' */
+            token = st.nextToken();
+
+            /* Read min range or "..." if range is absent */
+            token = st.nextToken();
+
+            if (token.equals("...") == false) {
+                if (!withRanges) {
+                    /*
+                     * Option have range, but asked for options without
+                     * ranges => skip it
+                     */
+                    continue;
+                }
+
+                /* Mark this option as option which range is defined in VM */
+                option.optionWithRange();
+
+                option.setMin(token);
+
+                /* Read "..." and skip it */
+                token = st.nextToken();
+
+                /* Get max value */
+                token = st.nextToken();
+                option.setMax(token);
+            } else if (withRanges) {
+                /*
+                 * Option not have range, but asked for options with
+                 * ranges => skip it
+                 */
+                continue;
+            }
+
+            /* Skip ']' */
+            token = st.nextToken();
+
+            /* Read origin of the option */
+            token = st.nextToken();
+
+            while (st.hasMoreTokens()) {
+                token += st.nextToken();
+            };
+            token = token.substring(1, token.indexOf("}"));
+
+            if (acceptOrigin.test(token)) {
+                addTypeDependency(option, token);
+                addNameDependency(option);
+
+                allOptions.put(name, option);
+            }
+        }
+
+        return allOptions;
+    }
+
+    static void failedMessage(String optionName, String value, boolean valid, String message) {
+        String temp;
+
+        if (valid) {
+            temp = "valid";
+        } else {
+            temp = "invalid";
+        }
+
+        failedMessage(String.format("Error processing option %s with %s value '%s'! %s",
+                optionName, temp, value, message));
+    }
+
+    static void failedMessage(String message) {
+        System.err.println("TEST FAILED: " + message);
+        finalFailedMessage.append(String.format("(%s)%n", message));
+    }
+
+    static void printOutputContent(OutputAnalyzer output) {
+        System.err.println(String.format("stdout content[%s]", output.getStdout()));
+        System.err.println(String.format("stderr content[%s]%n", output.getStderr()));
+    }
+
+    /**
+     * Return string with accumulated failure messages
+     *
+     * @return string with accumulated failure messages
+     */
+    public static String getMessageWithFailures() {
+        return finalFailedMessage.toString();
+    }
+
+    /**
+     * Run command line tests for options passed in the list
+     *
+     * @param options list of options to test
+     * @return number of failed tests
+     * @throws Exception if java process can not be started
+     */
+    public static int runCommandLineTests(List<? extends JVMOption> options) throws Exception {
+        int failed = 0;
+
+        for (JVMOption option : options) {
+            failed += option.testCommandLine();
+        }
+
+        return failed;
+    }
+
+    /**
+     * Test passed options using DynamicVMOption isValidValue and isInvalidValue
+     * methods. Only tests writeable options.
+     *
+     * @param options list of options to test
+     * @return number of failed tests
+     */
+    public static int runDynamicTests(List<? extends JVMOption> options) {
+        int failed = 0;
+
+        for (JVMOption option : options) {
+            failed += option.testDynamic();
+        }
+
+        return failed;
+    }
+
+    /**
+     * Test passed options using Jcmd. Only tests writeable options.
+     *
+     * @param options list of options to test
+     * @return number of failed tests
+     */
+    public static int runJcmdTests(List<? extends JVMOption> options) {
+        int failed = 0;
+
+        for (JVMOption option : options) {
+            failed += option.testJcmd();
+        }
+
+        return failed;
+    }
+
+    /**
+     * Test passed option using attach method. Only tests writeable options.
+     *
+     * @param options list of options to test
+     * @return number of failed tests
+     * @throws Exception if an error occurred while attaching to the target JVM
+     */
+    public static int runAttachTests(List<? extends JVMOption> options) throws Exception {
+        int failed = 0;
+
+        for (JVMOption option : options) {
+            failed += option.testAttach();
+        }
+
+        return failed;
+    }
+
+    /**
+     * Get JVM options as map. Can return options with defined ranges or options
+     * without range depending on "withRanges" argument. "acceptOrigin"
+     * predicate can be used to filter option origin.
+     *
+     * @param withRanges true if needed options with defined ranges inside JVM
+     * @param acceptOrigin predicate for option origins. Origins can be
+     * "product", "diagnostic" etc. Accept option only if acceptOrigin evaluates
+     * to true.
+     * @param additionalArgs additional arguments to the Java process which ran
+     * with "-XX:+PrintFlagsRanges"
+     * @return map from option name to the JVMOption object
+     * @throws Exception if a new process can not be created or an error
+     * occurred while reading the data
+     */
+    public static Map<String, JVMOption> getOptionsAsMap(boolean withRanges, Predicate<String> acceptOrigin,
+            String... additionalArgs) throws Exception {
+        Map<String, JVMOption> result;
+        Process p;
+        List<String> runJava = new ArrayList<>();
+
+        if (additionalArgs.length > 0) {
+            runJava.addAll(Arrays.asList(additionalArgs));
+        }
+
+        if (VMType != null) {
+            runJava.add(VMType);
+        }
+        runJava.add(PRINT_FLAGS_RANGES);
+        runJava.add("-version");
+
+        p = ProcessTools.createJavaProcessBuilder(runJava.toArray(new String[0])).start();
+
+        result = getJVMOptions(new InputStreamReader(p.getInputStream()), withRanges, acceptOrigin);
+
+        p.waitFor();
+
+        return result;
+    }
+
+    /**
+     * Get JVM options as list. Can return options with defined ranges or
+     * options without range depending on "withRanges" argument. "acceptOrigin"
+     * predicate can be used to filter option origin.
+     *
+     * @param withRanges true if needed options with defined ranges inside JVM
+     * @param acceptOrigin predicate for option origins. Origins can be
+     * "product", "diagnostic" etc. Accept option only if acceptOrigin evaluates
+     * to true.
+     * @param additionalArgs additional arguments to the Java process which ran
+     * with "-XX:+PrintFlagsRanges"
+     * @return List of options
+     * @throws Exception if a new process can not be created or an error
+     * occurred while reading the data
+     */
+    public static List<JVMOption> getOptions(boolean withRanges, Predicate<String> acceptOrigin,
+            String... additionalArgs) throws Exception {
+        return new ArrayList<>(getOptionsAsMap(withRanges, acceptOrigin, additionalArgs).values());
+    }
+
+    /**
+     * Get JVM options with ranges as list. "acceptOrigin" predicate can be used
+     * to filter option origin.
+     *
+     * @param acceptOrigin predicate for option origins. Origins can be
+     * "product", "diagnostic" etc. Accept option only if acceptOrigin evaluates
+     * to true.
+     * @param additionalArgs additional arguments to the Java process which ran
+     * with "-XX:+PrintFlagsRanges"
+     * @return List of options
+     * @throws Exception if a new process can not be created or an error
+     * occurred while reading the data
+     */
+    public static List<JVMOption> getOptionsWithRange(Predicate<String> acceptOrigin, String... additionalArgs) throws Exception {
+        return getOptions(true, acceptOrigin, additionalArgs);
+    }
+
+    /**
+     * Get JVM options with ranges as list.
+     *
+     * @param additionalArgs additional arguments to the Java process which ran
+     * with "-XX:+PrintFlagsRanges"
+     * @return list of options
+     * @throws Exception if a new process can not be created or an error
+     * occurred while reading the data
+     */
+    public static List<JVMOption> getOptionsWithRange(String... additionalArgs) throws Exception {
+        return getOptionsWithRange(origin -> true, additionalArgs);
+    }
+
+    /**
+     * Get JVM options with range as map. "acceptOrigin" predicate can be used
+     * to filter option origin.
+     *
+     * @param acceptOrigin predicate for option origins. Origins can be
+     * "product", "diagnostic" etc. Accept option only if acceptOrigin evaluates
+     * to true.
+     * @param additionalArgs additional arguments to the Java process which ran
+     * with "-XX:+PrintFlagsRanges"
+     * @return Map from option name to the JVMOption object
+     * @throws Exception if a new process can not be created or an error
+     * occurred while reading the data
+     */
+    public static Map<String, JVMOption> getOptionsWithRangeAsMap(Predicate<String> acceptOrigin, String... additionalArgs) throws Exception {
+        return getOptionsAsMap(true, acceptOrigin, additionalArgs);
+    }
+
+    /**
+     * Get JVM options with range as map
+     *
+     * @param additionalArgs additional arguments to the Java process which ran
+     * with "-XX:+PrintFlagsRanges"
+     * @return map from option name to the JVMOption object
+     * @throws Exception if a new process can not be created or an error
+     * occurred while reading the data
+     */
+    public static Map<String, JVMOption> getOptionsWithRangeAsMap(String... additionalArgs) throws Exception {
+        return getOptionsWithRangeAsMap(origin -> true, additionalArgs);
+    }
+
+    /* Simple method to test that java start-up. Used for testing options. */
+    public static void main(String[] args) {
+        System.out.print("Java start-up!");
+    }
+}