CommandLineOptionTest.java revision 2224:2a8815d86b93
1210284Sjmallett/*
2215990Sjmallett * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
3215990Sjmallett * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4210284Sjmallett *
5210284Sjmallett * This code is free software; you can redistribute it and/or modify it
6215990Sjmallett * under the terms of the GNU General Public License version 2 only, as
7215990Sjmallett * published by the Free Software Foundation.
8215990Sjmallett *
9210284Sjmallett * This code is distributed in the hope that it will be useful, but WITHOUT
10215990Sjmallett * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11215990Sjmallett * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12210284Sjmallett * version 2 for more details (a copy is included in the LICENSE file that
13215990Sjmallett * accompanied this code).
14215990Sjmallett *
15215990Sjmallett * You should have received a copy of the GNU General Public License version
16215990Sjmallett * 2 along with this work; if not, write to the Free Software Foundation,
17215990Sjmallett * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18215990Sjmallett *
19215990Sjmallett * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20215990Sjmallett * or visit www.oracle.com if you need additional information or have any
21215990Sjmallett * questions.
22215990Sjmallett */
23215990Sjmallett
24215990Sjmallettpackage jdk.test.lib.cli;
25215990Sjmallett
26215990Sjmallettimport java.util.List;
27215990Sjmallettimport java.util.ArrayList;
28215990Sjmallettimport java.util.Collections;
29215990Sjmallettimport java.util.function.BooleanSupplier;
30215990Sjmallett
31215990Sjmallettimport jdk.test.lib.process.ExitCode;
32215990Sjmallettimport jdk.test.lib.process.ProcessTools;
33215990Sjmallettimport jdk.test.lib.process.OutputAnalyzer;
34215990Sjmallettimport jdk.test.lib.Platform;
35215990Sjmallettimport jdk.test.lib.Utils;
36215990Sjmallett
37215990Sjmallett/**
38210284Sjmallett * Base class for command line option tests.
39210284Sjmallett */
40210284Sjmallettpublic abstract class CommandLineOptionTest {
41210284Sjmallett    public static final String UNLOCK_DIAGNOSTIC_VM_OPTIONS
42210284Sjmallett            = "-XX:+UnlockDiagnosticVMOptions";
43210284Sjmallett    public static final String UNLOCK_EXPERIMENTAL_VM_OPTIONS
44210284Sjmallett            = "-XX:+UnlockExperimentalVMOptions";
45215990Sjmallett    protected static final String UNRECOGNIZED_OPTION_ERROR_FORMAT
46210284Sjmallett            = "Unrecognized VM option '[+-]?%s(=.*)?'";
47210284Sjmallett    protected static final String EXPERIMENTAL_OPTION_ERROR_FORMAT
48210284Sjmallett            = "VM option '%s' is experimental and must be enabled via "
49210284Sjmallett            + "-XX:\\+UnlockExperimentalVMOptions.";
50210284Sjmallett    protected static final String DIAGNOSTIC_OPTION_ERROR_FORMAT
51215990Sjmallett            = " VM option '%s' is diagnostic and must be enabled via "
52210284Sjmallett            + "-XX:\\+UnlockDiagnosticVMOptions.";
53210284Sjmallett    private static final String PRINT_FLAGS_FINAL_FORMAT = "%s\\s*:?=\\s*%s";
54215990Sjmallett
55215990Sjmallett    /**
56210284Sjmallett     * Verifies that JVM startup behavior matches our expectations.
57215990Sjmallett     *
58215990Sjmallett     * @param option an option that should be passed to JVM
59215990Sjmallett     * @param expectedMessages an array of patterns that should occur
60210284Sjmallett     *                          in JVM output. If {@code null} then
61210284Sjmallett     *                          JVM output could be empty.
62215990Sjmallett     * @param unexpectedMessages an array of patterns that should not
63215990Sjmallett     *                           occur in JVM output. If {@code null} then
64210284Sjmallett     *                           JVM output could be empty.
65215990Sjmallett     * @param exitErrorMessage message that will be shown if exit code is not
66215990Sjmallett     *                           as expected.
67215990Sjmallett     * @param wrongWarningMessage message that will be shown if warning
68215990Sjmallett     *                           messages are not as expected.
69215990Sjmallett     * @param exitCode expected exit code.
70215990Sjmallett     * @throws Throwable if verification fails or some other issues occur.
71215990Sjmallett     */
72210284Sjmallett    public static void verifyJVMStartup(String option,
73215990Sjmallett            String expectedMessages[], String unexpectedMessages[],
74215990Sjmallett            String exitErrorMessage, String wrongWarningMessage,
75215990Sjmallett            ExitCode exitCode) throws Throwable {
76215990Sjmallett        CommandLineOptionTest.verifyJVMStartup(expectedMessages,
77215990Sjmallett                unexpectedMessages, exitErrorMessage,
78215990Sjmallett                wrongWarningMessage, exitCode, false, option);
79215990Sjmallett    }
80215990Sjmallett
81215990Sjmallett    /**
82215990Sjmallett     * Verifies that JVM startup behavior matches our expectations.
83215990Sjmallett     *
84215990Sjmallett     * @param expectedMessages an array of patterns that should occur
85215990Sjmallett     *                         in JVM output. If {@code null} then
86215990Sjmallett     *                         JVM output could be empty.
87215990Sjmallett     * @param unexpectedMessages an array of patterns that should not
88215990Sjmallett     *                           occur in JVM output. If {@code null} then
89215990Sjmallett     *                           JVM output could be empty.
90215990Sjmallett     * @param exitErrorMessage message that will be shown if exit code is not
91210284Sjmallett     *                           as expected.
92215990Sjmallett     * @param wrongWarningMessage message that will be shown if warning
93215990Sjmallett     *                           messages are not as expected.
94215990Sjmallett     * @param exitCode expected exit code.
95215990Sjmallett     * @param addTestVMOptions if {@code true} then test VM options will be
96215990Sjmallett     *                         passed to VM.
97215990Sjmallett     * @param options options that should be passed to VM in addition to mode
98215990Sjmallett     *                flag.
99215990Sjmallett     * @throws Throwable if verification fails or some other issues occur.
100215990Sjmallett     */
101215990Sjmallett    public static void verifyJVMStartup(String expectedMessages[],
102210284Sjmallett            String unexpectedMessages[], String exitErrorMessage,
103210284Sjmallett            String wrongWarningMessage, ExitCode exitCode,
104210284Sjmallett            boolean addTestVMOptions, String... options)
105210284Sjmallett                    throws Throwable {
106210284Sjmallett        List<String> finalOptions = new ArrayList<>();
107215990Sjmallett        if (addTestVMOptions) {
108210284Sjmallett            Collections.addAll(finalOptions, ProcessTools.getVmInputArgs());
109210284Sjmallett            Collections.addAll(finalOptions, Utils.getTestJavaOpts());
110210284Sjmallett        }
111210284Sjmallett        Collections.addAll(finalOptions, options);
112210284Sjmallett        finalOptions.add("-version");
113210284Sjmallett
114210284Sjmallett        ProcessBuilder processBuilder
115210284Sjmallett                = ProcessTools.createJavaProcessBuilder(finalOptions.toArray(
116215990Sjmallett                new String[finalOptions.size()]));
117210284Sjmallett        OutputAnalyzer outputAnalyzer
118210284Sjmallett                = new OutputAnalyzer(processBuilder.start());
119210284Sjmallett
120210284Sjmallett        try {
121210284Sjmallett                outputAnalyzer.shouldHaveExitValue(exitCode.value);
122210284Sjmallett        } catch (RuntimeException e) {
123215990Sjmallett            String errorMessage = String.format(
124215990Sjmallett                    "JVM process should have exit value '%d'.%n%s",
125215990Sjmallett                    exitCode.value, exitErrorMessage);
126215990Sjmallett            throw new AssertionError(errorMessage, e);
127215990Sjmallett        }
128215990Sjmallett
129215990Sjmallett        verifyOutput(expectedMessages, unexpectedMessages,
130215990Sjmallett                wrongWarningMessage, outputAnalyzer);
131210284Sjmallett    }
132215990Sjmallett
133215990Sjmallett    /**
134210284Sjmallett     * Verifies that JVM startup behavior matches our expectations.
135215990Sjmallett     *
136215990Sjmallett     * @param expectedMessages an array of patterns that should occur in JVM
137210284Sjmallett     *                         output. If {@code null} then
138215990Sjmallett     *                         JVM output could be empty.
139215990Sjmallett     * @param unexpectedMessages an array of patterns that should not occur
140215990Sjmallett     *                           in JVM output. If {@code null} then
141210284Sjmallett     *                           JVM output could be empty.
142215990Sjmallett     * @param wrongWarningMessage message that will be shown if messages are
143215990Sjmallett     *                            not as expected.
144210284Sjmallett     * @param outputAnalyzer OutputAnalyzer instance
145215990Sjmallett     * @throws AssertionError if verification fails.
146215990Sjmallett     */
147215990Sjmallett    public static void verifyOutput(String[] expectedMessages,
148215990Sjmallett            String[] unexpectedMessages, String wrongWarningMessage,
149210284Sjmallett            OutputAnalyzer outputAnalyzer) {
150215990Sjmallett        if (expectedMessages != null) {
151215990Sjmallett            for (String expectedMessage : expectedMessages) {
152215990Sjmallett                try {
153215990Sjmallett                    outputAnalyzer.shouldMatch(expectedMessage);
154210284Sjmallett                } catch (RuntimeException e) {
155215990Sjmallett                    String errorMessage = String.format(
156210284Sjmallett                            "Expected message not found: '%s'.%n%s",
157215990Sjmallett                            expectedMessage, wrongWarningMessage);
158210284Sjmallett                    throw new AssertionError(errorMessage, e);
159215990Sjmallett                }
160215990Sjmallett            }
161215990Sjmallett        }
162215990Sjmallett
163215990Sjmallett        if (unexpectedMessages != null) {
164215990Sjmallett            for (String unexpectedMessage : unexpectedMessages) {
165215990Sjmallett                try {
166215990Sjmallett                    outputAnalyzer.shouldNotMatch(unexpectedMessage);
167215990Sjmallett                } catch (RuntimeException e) {
168215990Sjmallett                    String errorMessage = String.format(
169215990Sjmallett                            "Unexpected message found: '%s'.%n%s",
170215990Sjmallett                            unexpectedMessage, wrongWarningMessage);
171215990Sjmallett                    throw new AssertionError(errorMessage, e);
172215990Sjmallett                }
173215990Sjmallett            }
174210284Sjmallett        }
175215990Sjmallett    }
176215990Sjmallett
177215990Sjmallett    /**
178215990Sjmallett     * Verifies that JVM startup behavior matches our expectations when type
179215990Sjmallett     * of newly started VM is the same as the type of current.
180215990Sjmallett     *
181215990Sjmallett     * @param expectedMessages an array of patterns that should occur
182215990Sjmallett     *                         in JVM output. If {@code null} then
183215990Sjmallett     *                         JVM output could be empty.
184215990Sjmallett     * @param unexpectedMessages an array of patterns that should not
185215990Sjmallett     *                           occur in JVM output. If {@code null} then
186215990Sjmallett     *                           JVM output could be empty.
187215990Sjmallett     * @param exitErrorMessage Message that will be shown if exit value is not
188215990Sjmallett     *                           as expected.
189215990Sjmallett     * @param wrongWarningMessage message that will be shown if warning
190215990Sjmallett     *                           messages are not as expected.
191215990Sjmallett     * @param exitCode expected exit code.
192215990Sjmallett     * @param options options that should be passed to VM in addition to mode
193215990Sjmallett     *                flag.
194215990Sjmallett     * @throws Throwable if verification fails or some other issues occur.
195215990Sjmallett     */
196215990Sjmallett    public static void verifySameJVMStartup(String expectedMessages[],
197215990Sjmallett            String unexpectedMessages[], String exitErrorMessage,
198215990Sjmallett            String wrongWarningMessage, ExitCode exitCode, String... options)
199215990Sjmallett            throws Throwable {
200215990Sjmallett        List<String> finalOptions = new ArrayList<>();
201215990Sjmallett        finalOptions.add(CommandLineOptionTest.getVMTypeOption());
202215990Sjmallett        Collections.addAll(finalOptions, options);
203215990Sjmallett
204215990Sjmallett        CommandLineOptionTest.verifyJVMStartup(expectedMessages,
205215990Sjmallett                unexpectedMessages, exitErrorMessage,
206215990Sjmallett                wrongWarningMessage, exitCode, false,
207215990Sjmallett                finalOptions.toArray(new String[finalOptions.size()]));
208215990Sjmallett    }
209215990Sjmallett
210215990Sjmallett    /**
211215990Sjmallett     * Verifies that value of specified JVM option is the same as
212215990Sjmallett     * expected value.
213215990Sjmallett     * This method filter out option with {@code optionName}
214215990Sjmallett     * name from test java options.
215210284Sjmallett     *
216210284Sjmallett     * @param optionName a name of tested option.
217210284Sjmallett     * @param expectedValue expected value of tested option.
218210284Sjmallett     * @param optionErrorString message will be shown if option value is not as
219215990Sjmallett     *                         expected.
220210284Sjmallett     * @param additionalVMOpts additional options that should be
221210284Sjmallett     *                         passed to JVM.
222210284Sjmallett     * @throws Throwable if verification fails or some other issues occur.
223210284Sjmallett     */
224215990Sjmallett    public static void verifyOptionValue(String optionName,
225210284Sjmallett            String expectedValue, String optionErrorString,
226210284Sjmallett            String... additionalVMOpts) throws Throwable {
227210284Sjmallett        verifyOptionValue(optionName, expectedValue, optionErrorString,
228210284Sjmallett                true, additionalVMOpts);
229210284Sjmallett    }
230215990Sjmallett
231215990Sjmallett    /**
232215990Sjmallett     * Verifies that value of specified JVM option is the same as
233215990Sjmallett     * expected value.
234215990Sjmallett     * This method filter out option with {@code optionName}
235215990Sjmallett     * name from test java options.
236215990Sjmallett     *
237210284Sjmallett     * @param optionName a name of tested option.
238215990Sjmallett     * @param expectedValue expected value of tested option.
239210284Sjmallett     * @param addTestVmOptions if {@code true}, then test VM options
240215990Sjmallett     *                         will be used.
241215990Sjmallett     * @param optionErrorString message will be shown if option value is not as
242215990Sjmallett     *                         expected.
243210284Sjmallett     * @param additionalVMOpts additional options that should be
244215990Sjmallett     *                         passed to JVM.
245215990Sjmallett     * @throws Throwable if verification fails or some other issues
246215990Sjmallett     *                          occur.
247215990Sjmallett     */
248210284Sjmallett    public static void verifyOptionValue(String optionName,
249215990Sjmallett            String expectedValue, String optionErrorString,
250210284Sjmallett            boolean addTestVmOptions, String... additionalVMOpts)
251215990Sjmallett                    throws Throwable {
252215990Sjmallett        List<String> vmOpts = new ArrayList<>();
253215990Sjmallett
254215990Sjmallett        if (addTestVmOptions) {
255215990Sjmallett            Collections.addAll(vmOpts,
256215990Sjmallett                               Utils.getFilteredTestJavaOpts(optionName));
257215990Sjmallett        }
258215990Sjmallett        Collections.addAll(vmOpts, additionalVMOpts);
259215990Sjmallett        Collections.addAll(vmOpts, "-XX:+PrintFlagsFinal", "-version");
260215990Sjmallett
261215990Sjmallett        ProcessBuilder processBuilder = ProcessTools.createJavaProcessBuilder(
262215990Sjmallett                vmOpts.toArray(new String[vmOpts.size()]));
263215990Sjmallett
264215990Sjmallett        OutputAnalyzer outputAnalyzer
265215990Sjmallett                = new OutputAnalyzer(processBuilder.start());
266215990Sjmallett
267215990Sjmallett        try {
268215990Sjmallett            outputAnalyzer.shouldHaveExitValue(0);
269215990Sjmallett        } catch (RuntimeException e) {
270215990Sjmallett            String errorMessage = String.format(
271215990Sjmallett                    "JVM should start with option '%s' without errors.",
272215990Sjmallett                    optionName);
273215990Sjmallett            throw new AssertionError(errorMessage, e);
274215990Sjmallett        }
275215990Sjmallett        verifyOptionValue(optionName, expectedValue, optionErrorString,
276215990Sjmallett                outputAnalyzer);
277215990Sjmallett    }
278215990Sjmallett
279215990Sjmallett    /**
280215990Sjmallett     * Verifies that value of specified JVM option is the same as
281215990Sjmallett     * expected value.
282215990Sjmallett     *
283215990Sjmallett     * @param optionName a name of tested option.
284215990Sjmallett     * @param expectedValue expected value of tested option.
285215990Sjmallett     * @param optionErrorString message will be shown if option value is not
286215990Sjmallett     *                          as expected.
287215990Sjmallett     * @param outputAnalyzer OutputAnalyzer instance
288215990Sjmallett     * @throws AssertionError if verification fails
289215990Sjmallett     */
290215990Sjmallett    public static void verifyOptionValue(String optionName,
291215990Sjmallett            String expectedValue, String optionErrorString,
292215990Sjmallett            OutputAnalyzer outputAnalyzer) {
293215990Sjmallett        try {
294215990Sjmallett            outputAnalyzer.shouldMatch(String.format(
295210284Sjmallett                    CommandLineOptionTest.PRINT_FLAGS_FINAL_FORMAT,
296210284Sjmallett                    optionName, expectedValue));
297210284Sjmallett        } catch (RuntimeException e) {
298210284Sjmallett            String errorMessage = String.format(
299215990Sjmallett                    "Option '%s' is expected to have '%s' value%n%s",
300210284Sjmallett                    optionName, expectedValue,
301210284Sjmallett                    optionErrorString);
302210284Sjmallett            throw new AssertionError(errorMessage, e);
303210284Sjmallett        }
304215990Sjmallett    }
305210284Sjmallett
306210284Sjmallett    /**
307210284Sjmallett     * Start VM with given options and values.
308210284Sjmallett     * Generates command line option flags from
309215990Sjmallett     * {@code optionNames} and {@code optionValues}.
310210284Sjmallett     *
311210284Sjmallett     * @param optionNames names of options to pass in
312210284Sjmallett     * @param optionValues  values of option
313210284Sjmallett     * @param additionalVMOpts additional options that should be
314210284Sjmallett     *                         passed to JVM.
315215990Sjmallett     * @return output from vm process
316215990Sjmallett     */
317215990Sjmallett    public static OutputAnalyzer startVMWithOptions(String[] optionNames,
318215990Sjmallett            String[] optionValues,
319215990Sjmallett            String... additionalVMOpts) throws Throwable {
320215990Sjmallett        List<String> vmOpts = new ArrayList<>();
321210284Sjmallett        if (optionNames == null || optionValues == null || optionNames.length != optionValues.length) {
322215990Sjmallett            throw new IllegalArgumentException("optionNames and/or optionValues");
323210284Sjmallett        }
324215990Sjmallett
325215990Sjmallett        for (int i = 0; i < optionNames.length; i++) {
326215990Sjmallett          vmOpts.add(prepareFlag(optionNames[i], optionValues[i]));
327210284Sjmallett        }
328215990Sjmallett        Collections.addAll(vmOpts, additionalVMOpts);
329215990Sjmallett        Collections.addAll(vmOpts, "-version");
330215990Sjmallett
331215990Sjmallett        ProcessBuilder processBuilder = ProcessTools.createJavaProcessBuilder(
332215990Sjmallett                vmOpts.toArray(new String[vmOpts.size()]));
333215990Sjmallett
334215990Sjmallett        return new OutputAnalyzer(processBuilder.start());
335215990Sjmallett    }
336215990Sjmallett
337215990Sjmallett    /**
338215990Sjmallett     * Verifies from the output that values of specified JVM options were the same as
339215990Sjmallett     * expected values.
340215990Sjmallett     *
341215990Sjmallett     * @param outputAnalyzer search output for expect options and values.
342215990Sjmallett     * @param optionNames names of tested options.
343215990Sjmallett     * @param expectedValues expected values of tested options.
344215990Sjmallett     * @throws Throwable if verification fails or some other issues occur.
345215990Sjmallett     */
346215990Sjmallett    public static void verifyOptionValuesFromOutput(OutputAnalyzer outputAnalyzer,
347215990Sjmallett            String[] optionNames,
348215990Sjmallett            String[] expectedValues) throws Throwable {
349215990Sjmallett        outputAnalyzer.shouldHaveExitValue(0);
350215990Sjmallett        for (int i = 0; i < optionNames.length; i++) {
351215990Sjmallett          outputAnalyzer.shouldMatch(String.format(
352215990Sjmallett                CommandLineOptionTest.PRINT_FLAGS_FINAL_FORMAT,
353215990Sjmallett                optionNames[i], expectedValues[i]));
354215990Sjmallett        }
355215990Sjmallett    }
356215990Sjmallett
357215990Sjmallett   /**
358215990Sjmallett     * Verifies that value of specified JVM options are the same as
359215990Sjmallett     * expected values.
360215990Sjmallett     * Generates command line option flags from
361215990Sjmallett     * {@code optionNames} and {@code expectedValues}.
362215990Sjmallett     *
363215990Sjmallett     * @param optionNames names of tested options.
364215990Sjmallett     * @param expectedValues expected values of tested options.
365215990Sjmallett     * @throws Throwable if verification fails or some other issues occur.
366215990Sjmallett     */
367215990Sjmallett    public static void verifyOptionValues(String[] optionNames,
368215990Sjmallett            String[] expectedValues) throws Throwable {
369215990Sjmallett       OutputAnalyzer outputAnalyzer = startVMWithOptions(optionNames, expectedValues, "-XX:+PrintFlagsFinal");
370215990Sjmallett       verifyOptionValuesFromOutput(outputAnalyzer, optionNames, expectedValues);
371215990Sjmallett    }
372215990Sjmallett
373215990Sjmallett    /**
374215990Sjmallett     * Verifies that value of specified JVM when type of newly started VM
375215990Sjmallett     * is the same as the type of current.
376215990Sjmallett     * This method filter out option with {@code optionName}
377210284Sjmallett     * name from test java options.
378210284Sjmallett     * Only mode flag will be passed to VM in addition to
379210284Sjmallett     * {@code additionalVMOpts}
380210284Sjmallett     *
381215990Sjmallett     * @param optionName name of tested option.
382210284Sjmallett     * @param expectedValue expected value of tested option.
383210284Sjmallett     * @param optionErrorString message to show if option has another value
384210284Sjmallett     * @param additionalVMOpts additional options that should be
385210284Sjmallett     *                         passed to JVM.
386210284Sjmallett     * @throws Throwable if verification fails or some other issues occur.
387210284Sjmallett     */
388210284Sjmallett    public static void verifyOptionValueForSameVM(String optionName,
389210284Sjmallett            String expectedValue, String optionErrorString,
390210284Sjmallett            String... additionalVMOpts) throws Throwable {
391210284Sjmallett        List<String> finalOptions = new ArrayList<>();
392215990Sjmallett        finalOptions.add(CommandLineOptionTest.getVMTypeOption());
393210284Sjmallett        Collections.addAll(finalOptions, additionalVMOpts);
394210284Sjmallett
395210284Sjmallett        CommandLineOptionTest.verifyOptionValue(optionName, expectedValue,
396210284Sjmallett                optionErrorString, false,
397210284Sjmallett                finalOptions.toArray(new String[finalOptions.size()]));
398215990Sjmallett    }
399215990Sjmallett
400215990Sjmallett    /**
401215990Sjmallett     * Prepares boolean command line flag with name {@code name} according
402215990Sjmallett     * to it's {@code value}.
403215990Sjmallett     *
404215990Sjmallett     * @param name the name of option to be prepared
405210284Sjmallett     * @param value the value of option
406215990Sjmallett     * @return prepared command line flag
407215990Sjmallett     */
408210284Sjmallett    public static String prepareBooleanFlag(String name, boolean value) {
409215990Sjmallett        return String.format("-XX:%c%s", (value ? '+' : '-'), name);
410215990Sjmallett    }
411210284Sjmallett
412215990Sjmallett    /**
413215990Sjmallett     * Prepares numeric command line flag with name {@code name} by setting
414215990Sjmallett     * it's value to {@code value}.
415210284Sjmallett     *
416210284Sjmallett     * @param name the name of option to be prepared
417215990Sjmallett     * @param value the value of option
418215990Sjmallett     * @return prepared command line flag
419210284Sjmallett     */
420215990Sjmallett    public static String prepareNumericFlag(String name, Number value) {
421215990Sjmallett        return String.format("-XX:%s=%s", name, value.toString());
422210284Sjmallett    }
423215990Sjmallett
424215990Sjmallett    /**
425215990Sjmallett     * Prepares generic command line flag with name {@code name} by setting
426215990Sjmallett     * it's value to {@code value}.
427210284Sjmallett     *
428215990Sjmallett     * @param name the name of option to be prepared
429215990Sjmallett     * @param value the value of option ("+" or "-" can be used instead of "true" or "false")
430215990Sjmallett     * @return prepared command line flag
431215990Sjmallett     */
432215990Sjmallett    public static String prepareFlag(String name, String value) {
433215990Sjmallett        if (value.equals("+") || value.equalsIgnoreCase("true")) {
434215990Sjmallett          return "-XX:+" + name;
435215990Sjmallett      } else if (value.equals("-") || value.equalsIgnoreCase("false")) {
436215990Sjmallett        return "-XX:-" + name;
437215990Sjmallett      } else {
438215990Sjmallett        return "-XX:" + name + "=" + value;
439215990Sjmallett      }
440215990Sjmallett    }
441215990Sjmallett
442215990Sjmallett    /**
443215990Sjmallett     * Returns message that should occur in VM output if option
444215990Sjmallett     * {@code optionName} if unrecognized.
445215990Sjmallett     *
446215990Sjmallett     * @param optionName the name of option for which message should be returned
447215990Sjmallett     * @return message saying that option {@code optionName} is unrecognized
448215990Sjmallett     */
449215990Sjmallett    public static String getUnrecognizedOptionErrorMessage(String optionName) {
450215990Sjmallett        return String.format(
451215990Sjmallett                CommandLineOptionTest.UNRECOGNIZED_OPTION_ERROR_FORMAT,
452215990Sjmallett                optionName);
453215990Sjmallett    }
454215990Sjmallett
455215990Sjmallett    /**
456215990Sjmallett     * Returns message that should occur in VM output if option
457215990Sjmallett     * {@code optionName} is experimental and
458215990Sjmallett     * -XX:+UnlockExperimentalVMOptions was not passed to VM.
459215990Sjmallett     *
460215990Sjmallett     * @param optionName the name of option for which message should be returned
461215990Sjmallett     * @return message saying that option {@code optionName} is experimental
462215990Sjmallett     */
463215990Sjmallett    public static String getExperimentalOptionErrorMessage(String optionName) {
464215990Sjmallett        return String.format(
465215990Sjmallett                CommandLineOptionTest.EXPERIMENTAL_OPTION_ERROR_FORMAT,
466215990Sjmallett                optionName);
467215990Sjmallett    }
468215990Sjmallett
469215990Sjmallett    /**
470215990Sjmallett     * Returns message that should occur in VM output if option
471215990Sjmallett     * {@code optionName} is diagnostic and -XX:+UnlockDiagnosticVMOptions
472215990Sjmallett     * was not passed to VM.
473215990Sjmallett     *
474215990Sjmallett     * @param optionName the name of option for which message should be returned
475215990Sjmallett     * @return message saying that option {@code optionName} is diganostic
476215990Sjmallett     */
477215990Sjmallett    public static String getDiagnosticOptionErrorMessage(String optionName) {
478215990Sjmallett        return String.format(
479215990Sjmallett                CommandLineOptionTest.DIAGNOSTIC_OPTION_ERROR_FORMAT,
480215990Sjmallett                optionName);
481215990Sjmallett    }
482215990Sjmallett
483215990Sjmallett    /**
484215990Sjmallett     * @return option required to start a new VM with the same type as current.
485215990Sjmallett     * @throws RuntimeException when VM type is unknown.
486215990Sjmallett     */
487215990Sjmallett    private static String getVMTypeOption() {
488215990Sjmallett        if (Platform.isServer()) {
489215990Sjmallett            return "-server";
490215990Sjmallett        } else if (Platform.isClient()) {
491215990Sjmallett            return "-client";
492215990Sjmallett        } else if (Platform.isMinimal()) {
493215990Sjmallett            return "-minimal";
494215990Sjmallett        } else if (Platform.isGraal()) {
495215990Sjmallett            return "-graal";
496215990Sjmallett        }
497215990Sjmallett        throw new RuntimeException("Unknown VM mode.");
498215990Sjmallett    }
499215990Sjmallett
500215990Sjmallett    private final BooleanSupplier predicate;
501215990Sjmallett
502215990Sjmallett    /**
503215990Sjmallett     * Constructs new CommandLineOptionTest that will be executed only if
504215990Sjmallett     * predicate {@code predicate} return {@code true}.
505215990Sjmallett     * @param predicate a predicate responsible for test's preconditions check.
506210284Sjmallett     */
507    public CommandLineOptionTest(BooleanSupplier predicate) {
508        this.predicate = predicate;
509    }
510
511    /**
512     * Runs command line option test.
513     */
514    public final void test() throws Throwable {
515        if (predicate.getAsBoolean()) {
516            runTestCases();
517        }
518    }
519
520    /**
521     * @throws Throwable if some issue happened during test cases execution.
522     */
523    protected abstract void runTestCases() throws Throwable;
524}
525