CheckCompileCommandOption.java revision 11707:ad7af1afda7a
1/*
2 * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23
24/*
25 * @test CheckCompileCommandOption
26 * @summary Checks parsing of -XX:CompileCommand=option
27 * @bug 8055286 8056964 8059847 8069035
28 * @library /testlibrary
29 * @modules java.base/jdk.internal.misc
30 *          java.management
31 * @run driver compiler.oracle.CheckCompileCommandOption
32 */
33
34package compiler.oracle;
35
36import jdk.test.lib.OutputAnalyzer;
37import jdk.test.lib.ProcessTools;
38
39import java.io.File;
40
41public class CheckCompileCommandOption {
42
43    // Currently, two types of trailing options can be used with
44    // -XX:CompileCommand=option
45    //
46    // (1) CompileCommand=option,Klass::method,flag
47    // (2) CompileCommand=option,Klass::method,type,flag,value
48    //
49    // Type (1) is used to enable a boolean flag for a method.
50    //
51    // Type (2) is used to support flags with a value. Values can
52    // have the the following types: intx, uintx, bool, ccstr,
53    // ccstrlist, and double.
54
55    private static final String[][] FILE_ARGUMENTS = {
56        {
57            "-XX:CompileCommandFile=" + new File(System.getProperty("test.src", "."), "command1.txt"),
58            "-version"
59        },
60        {
61            "-XX:CompileCommandFile=" + new File(System.getProperty("test.src", "."), "command2.txt"),
62            "-version"
63        }
64    };
65
66    private static final String[][] FILE_EXPECTED_OUTPUT = {
67        {
68            "CompileCommand: option com/oracle/Test.test bool MyBoolOption1 = true",
69            "CompileCommand: option com/oracle/Test.test bool MyBoolOption2 = true",
70            "CompileCommand: option com/oracle/Test.test bool MyBoolOption3 = true",
71            "CompileCommand: option com/oracle/Test.test bool MyBoolOption5 = true",
72            "CompileCommand: option com/oracle/Test.test bool MyBoolOption6 = true",
73            "CompileCommand: option com/oracle/Test.test bool MyBoolOption7 = true",
74            "CompileCommand: option com/oracle/Test.test bool MyBoolOption8 = true",
75            "CompileCommand: option com/oracle/Test.test(I) bool MyBoolOption9 = true",
76            "CompileCommand: option com/oracle/Test.test(I) bool MyBoolOption10 = true",
77            "CompileCommand: option com/oracle/Test.test(I) bool MyBoolOption11 = true",
78            "CompileCommand: option com/oracle/Test.test(I) bool MyBoolOption13 = true",
79            "CompileCommand: option com/oracle/Test.test(I) bool MyBoolOption14 = true",
80            "CompileCommand: option com/oracle/Test.test(I) bool MyBoolOption15 = true",
81            "CompileCommand: option com/oracle/Test.test(I) bool MyBoolOption16 = true"
82        },
83        {
84            "CompileCommand: option Test.test const char* MyListOption = '_foo _bar'",
85            "CompileCommand: option Test.test const char* MyStrOption = '_foo'",
86            "CompileCommand: option Test.test bool MyBoolOption = false",
87            "CompileCommand: option Test.test intx MyIntxOption = -1",
88            "CompileCommand: option Test.test uintx MyUintxOption = 1",
89            "CompileCommand: option Test.test bool MyFlag = true",
90            "CompileCommand: option Test.test double MyDoubleOption = 1.123000"
91        }
92    };
93
94    private static final String[][] TYPE_1_ARGUMENTS = {
95        {
96            "-XX:CompileCommand=option,com/oracle/Test.test,MyBoolOption1",
97            "-XX:CompileCommand=option,com/oracle/Test,test,MyBoolOption2",
98            "-XX:CompileCommand=option,com.oracle.Test::test,MyBoolOption3",
99            "-XX:CompileCommand=option,com/oracle/Test.test,MyBoolOption5,MyBoolOption6",
100            "-XX:CompileCommand=option,com/oracle/Test,test,MyBoolOption7,MyBoolOption8",
101            "-version"
102        }
103    };
104
105    private static final String[][] TYPE_1_EXPECTED_OUTPUTS = {
106        {
107            "CompileCommand: option com/oracle/Test.test bool MyBoolOption1 = true",
108            "CompileCommand: option com/oracle/Test.test bool MyBoolOption2 = true",
109            "CompileCommand: option com/oracle/Test.test bool MyBoolOption3 = true",
110            "CompileCommand: option com/oracle/Test.test bool MyBoolOption5 = true",
111            "CompileCommand: option com/oracle/Test.test bool MyBoolOption6 = true",
112            "CompileCommand: option com/oracle/Test.test bool MyBoolOption7 = true",
113            "CompileCommand: option com/oracle/Test.test bool MyBoolOption8 = true"
114        }
115    };
116
117    private static final String[][] TYPE_2_ARGUMENTS = {
118        {
119            "-XX:CompileCommand=option,Test::test,ccstrlist,MyListOption,_foo,_bar",
120            "-XX:CompileCommand=option,Test::test,ccstr,MyStrOption,_foo",
121            "-XX:CompileCommand=option,Test::test,bool,MyBoolOption,false",
122            "-XX:CompileCommand=option,Test::test,intx,MyIntxOption,-1",
123            "-XX:CompileCommand=option,Test::test,uintx,MyUintxOption,1",
124            "-XX:CompileCommand=option,Test::test,MyFlag",
125            "-XX:CompileCommand=option,Test::test,double,MyDoubleOption1,1.123",
126            "-XX:CompileCommand=option,Test.test,double,MyDoubleOption2,1.123",
127            "-XX:CompileCommand=option,Test::test,bool,MyBoolOptionX,false,intx,MyIntxOptionX,-1,uintx,MyUintxOptionX,1,MyFlagX,double,MyDoubleOptionX,1.123",
128            "-version"
129        }
130    };
131
132    private static final String[][] TYPE_2_EXPECTED_OUTPUTS = {
133        {
134            "CompileCommand: option Test.test const char* MyListOption = '_foo _bar'",
135            "CompileCommand: option Test.test const char* MyStrOption = '_foo'",
136            "CompileCommand: option Test.test bool MyBoolOption = false",
137            "CompileCommand: option Test.test intx MyIntxOption = -1",
138            "CompileCommand: option Test.test uintx MyUintxOption = 1",
139            "CompileCommand: option Test.test bool MyFlag = true",
140            "CompileCommand: option Test.test double MyDoubleOption1 = 1.123000",
141            "CompileCommand: option Test.test double MyDoubleOption2 = 1.123000",
142            "CompileCommand: option Test.test bool MyBoolOptionX = false",
143            "CompileCommand: option Test.test intx MyIntxOptionX = -1",
144            "CompileCommand: option Test.test uintx MyUintxOptionX = 1",
145            "CompileCommand: option Test.test bool MyFlagX = true",
146            "CompileCommand: option Test.test double MyDoubleOptionX = 1.123000",
147        }
148    };
149
150    private static final String[][] TYPE_2_INVALID_ARGUMENTS = {
151        {
152            // bool flag name missing
153            "-XX:CompileCommand=option,Test::test,bool",
154            "-version"
155        },
156        {
157            // bool flag value missing
158            "-XX:CompileCommand=option,Test::test,bool,MyBoolOption",
159            "-version"
160        },
161        {
162            // wrong value for bool flag
163            "-XX:CompileCommand=option,Test::test,bool,MyBoolOption,100",
164            "-version"
165        },
166        {
167            // intx flag name missing
168            "-XX:CompileCommand=option,Test::test,bool,MyBoolOption,false,intx",
169            "-version"
170        },
171        {
172            // intx flag value missing
173            "-XX:CompileCommand=option,Test::test,bool,MyBoolOption,false,intx,MyIntOption",
174            "-version"
175        },
176        {
177            // wrong value for intx flag
178            "-XX:CompileCommand=option,Test::test,bool,MyBoolOption,false,intx,MyIntOption,true",
179            "-version"
180        },
181        {
182            // wrong value for flag double flag
183            "-XX:CompileCommand=option,Test::test,double,MyDoubleOption,1",
184            "-version"
185        }
186    };
187
188    private static void verifyValidOption(String[] arguments, String[] expected_outputs) throws Exception {
189        ProcessBuilder pb;
190        OutputAnalyzer out;
191
192        pb = ProcessTools.createJavaProcessBuilder(arguments);
193        out = new OutputAnalyzer(pb.start());
194
195        for (String expected_output : expected_outputs) {
196            out.shouldContain(expected_output);
197        }
198
199        out.shouldNotContain("CompileCommand: An error occurred during parsing");
200        out.shouldHaveExitValue(0);
201    }
202
203    private static void verifyInvalidOption(String[] arguments) throws Exception {
204        ProcessBuilder pb;
205        OutputAnalyzer out;
206
207        pb = ProcessTools.createJavaProcessBuilder(arguments);
208        out = new OutputAnalyzer(pb.start());
209
210        out.shouldContain("CompileCommand: An error occurred during parsing");
211        out.shouldHaveExitValue(0);
212    }
213
214    public static void main(String[] args) throws Exception {
215
216        if (TYPE_1_ARGUMENTS.length != TYPE_1_EXPECTED_OUTPUTS.length) {
217            throw new RuntimeException("Test is set up incorrectly: length of arguments and expected outputs for type (1) options does not match.");
218        }
219
220        if (TYPE_2_ARGUMENTS.length != TYPE_2_EXPECTED_OUTPUTS.length) {
221            throw new RuntimeException("Test is set up incorrectly: length of arguments and expected outputs for type (2) options does not match.");
222        }
223
224        // Check if type (1) options are parsed correctly
225        for (int i = 0; i < TYPE_1_ARGUMENTS.length; i++) {
226            verifyValidOption(TYPE_1_ARGUMENTS[i], TYPE_1_EXPECTED_OUTPUTS[i]);
227        }
228
229        // Check if type (2) options are parsed correctly
230        for (int i = 0; i < TYPE_2_ARGUMENTS.length; i++) {
231            verifyValidOption(TYPE_2_ARGUMENTS[i], TYPE_2_EXPECTED_OUTPUTS[i]);
232        }
233
234        // Check if error is reported for invalid type (2) options
235        // (flags with type information specified)
236        for (String[] arguments: TYPE_2_INVALID_ARGUMENTS) {
237            verifyInvalidOption(arguments);
238        }
239
240        // Check if commands in command file are parsed correctly
241        for (int i = 0; i < FILE_ARGUMENTS.length; i++) {
242            verifyValidOption(FILE_ARGUMENTS[i], FILE_EXPECTED_OUTPUT[i]);
243        }
244    }
245}
246