File: OptionSmokeTest.java

package info (click to toggle)
openjdk-25 25.0.1%2B8-1~deb13u1
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 825,408 kB
  • sloc: java: 5,585,680; cpp: 1,333,948; xml: 1,321,242; ansic: 488,034; asm: 404,003; objc: 21,088; sh: 15,106; javascript: 13,265; python: 8,319; makefile: 2,518; perl: 357; awk: 351; pascal: 103; exp: 83; sed: 72; jsp: 24
file content (306 lines) | stat: -rw-r--r-- 13,484 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
/*
 * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

/**
 * @test
 * @bug 8196433 8307168
 * @summary use the new error diagnostic approach at javac.Main
 * @library /tools/lib
 * @modules jdk.compiler/com.sun.tools.javac.api
 *          jdk.compiler/com.sun.tools.javac.code
 *          jdk.compiler/com.sun.tools.javac.main
 *          jdk.compiler/com.sun.tools.javac.util
 *          jdk.jdeps/com.sun.tools.javap
 * @build toolbox.ToolBox toolbox.JavacTask toolbox.TestRunner
 * @run main/othervm OptionSmokeTest
 */

import java.util.Locale;

import java.util.List;
import java.util.stream.Collectors;

import java.nio.file.Path;
import java.nio.file.Paths;

import com.sun.tools.javac.util.Assert;
import com.sun.tools.javac.code.Source;

import toolbox.TestRunner;
import toolbox.ToolBox;
import toolbox.JavacTask;
import toolbox.Task;

public class OptionSmokeTest extends TestRunner {
    ToolBox tb = new ToolBox();

    public OptionSmokeTest() {
        super(System.err);
        Locale.setDefault(Locale.US);
    }

    protected void runTests() throws Exception {
        runTests(m -> new Object[] { Paths.get(m.getName()) });
    }

    Path[] findJavaFiles(Path... paths) throws Exception {
        return tb.findJavaFiles(paths);
    }

    public static void main(String... args) throws Exception {
        new OptionSmokeTest().runTests();
    }

    @Test
    public void optionA1(Path base) throws Exception {
        doTest(base, "error: -A requires an argument; use '-Akey' or '-Akey=value'", "-A");
    }

    @Test
    public void optionA2(Path base) throws Exception {
        doTest(base,
                "error: key in annotation processor option '-A1e=2' is not a dot-separated sequence of identifiers",
                "-A1e=2");
    }

    @Test
    public void noFlag(Path base) throws Exception {
        doTest(base, "error: invalid flag: -noFlag", "-noFlag");
    }

    @Test
    public void profileAndBSP(Path base) throws Exception {
        doTest(base, "error: profile and bootclasspath options cannot be used together",
                String.format("-profile compact1 -bootclasspath . -target %s -source %s", Source.DEFAULT.name, Source.DEFAULT.name));
    }

    @Test
    public void invalidProfile(Path base) throws Exception {
        doTest(base, "error: invalid profile: noProfile", "-profile noProfile");
    }

    @Test
    public void invalidTarget(Path base) throws Exception {
        doTest(base, "error: invalid target release: 999999", "-target 999999");
    }

    @Test
    public void optionNotAvailableWithTarget(Path base) throws Exception {
        doTest(base, String.format("error: option -profile not allowed with target %s", Source.DEFAULT.name),
                String.format("-profile compact1 -target %s", Source.DEFAULT.name));
    }

    @Test
    public void optionTooMany(Path base) throws Exception {
        doTest(base, "error: option --default-module-for-created-files can only be specified once",
                "--default-module-for-created-files=m1x --default-module-for-created-files=m1x");
    }

    @Test
    public void noSrcFiles(Path base) throws Exception {
        doTestNoSource(base, "error: no source files", String.format("-target %s", Source.DEFAULT.name));
    }

    @Test
    public void requiresArg(Path base) throws Exception {
        doTestNoSource(base, "error: --target requires an argument", "-target");
    }

    @Test
    public void invalidSource(Path base) throws Exception {
        doTestNoSource(base, "error: invalid source release: 999999", "-source 999999");
    }

    @Test
    public void sourceAndModuleSourceCantBeTogether(Path base) throws Exception {
        doTest(base, "error: cannot specify both --source-path and --module-source-path",
                "--source-path . --module-source-path .");
    }

    @Test
    public void sourceAndTargetMismatch(Path base) throws Exception {
        doTest(base, String.format("error: specified target release %s is too old for the specified source release %s", Source.MIN.name, Source.DEFAULT.name),
                String.format("-source %s -target %s", Source.DEFAULT.name, Source.MIN.name));
    }

    @Test
    public void targetConflictsWithDefaultSource(Path base) throws Exception {
        doTest(base, String.format("error: specified target release %s is too old for the default source release %s", Source.MIN.name, Source.DEFAULT.name),
                String.format("-target %s", Source.MIN.name));
    }

//     @Test
//     public void profileNotValidForTarget(Path base) throws Exception {
//         doTest(base, String.format("warning: profile compact2 is not valid for target release %s", Source.MIN.name),
//                 String.format("-profile compact2 -target %s -source %s", Source.MIN.name, Source.MIN.name));
//     }

    @Test
    public void fileNotFound(Path base) throws Exception {
        String log = new JavacTask(tb, Task.Mode.CMDLINE)
                .files("notExistent/T.java")
                .run(Task.Expect.FAIL)
                .writeAll()
                .getOutput(Task.OutputKind.DIRECT);
        Assert.check(log.startsWith(String.format("error: file not found: notExistent%sT.java", fileSeparator)),
                String.format("real value of log:%s", log));
    }

    static final String fileSeparator = System.getProperty("file.separator");

    @Test
    public void notADirectory(Path base) throws Exception {
        doTest(base, String.format("error: not a directory: notADirectory%ssrc%sDummy.java", fileSeparator, fileSeparator),
                String.format("-d notADirectory%ssrc%sDummy.java", fileSeparator, fileSeparator));
    }

    @Test
    public void notAFile(Path base) throws Exception {
        // looks like a java file, it is a directory
        Path dir = base.resolve("dir.java");
        tb.createDirectories(dir);
        String log = new JavacTask(tb, Task.Mode.CMDLINE)
                .spaceSeparatedOptions("-XDsourcefile " + dir)
                .run(Task.Expect.FAIL)
                .writeAll()
                .getOutput(Task.OutputKind.DIRECT);
        Assert.check(log.startsWith(String.format("error: not a file: notAFile%sdir.java", fileSeparator)));
    }

    @Test
    public void badValueForOption(Path base) throws Exception {
        doTestNoSource(base, "error: bad value for --patch-module option: \'notExistent\'",
                "--patch-module notExistent");
    }

    @Test
    public void patchModuleMoreThanOnce(Path base) throws Exception {
        doTestNoSource(base, "error: --patch-module specified more than once for m",
                "--patch-module m=. --patch-module m=.");
    }

    @Test
    public void unmatchedQuoteInEnvVar(Path base) throws Exception {
        Path src = base.resolve("src");
        tb.writeJavaFiles(src, "class Dummy {}");
        List<String> log = new JavacTask(tb, Task.Mode.EXEC)
                .envVar("JDK_JAVAC_OPTIONS",
                        String.format("--add-exports jdk.compiler%scom.sun.tools.javac.jvm=\"ALL-UNNAMED", fileSeparator))
                .options("-J-Duser.language=en", "-J-Duser.country=US")
                .files(findJavaFiles(src))
                .run(Task.Expect.FAIL)
                .writeAll()
                .getOutputLines(Task.OutputKind.STDERR);
        log = log.stream().filter(s->!s.matches("^Picked up .*JAVA.*OPTIONS:.*")).collect(Collectors.toList());
        List<String> expected = List.of(
                "error: unmatched quote in environment variable JDK_JAVAC_OPTIONS",
                "Usage: javac <options> <source files>",
                "use --help for a list of possible options"
        );
        tb.checkEqual(log, expected);
    }

    @Test
    public void optionCantBeUsedWithRelease(Path base) throws Exception {
        doTestNoSource(base, "error: option --source cannot be used together with --release",
                String.format("--release %s -source %s", Source.DEFAULT.name, Source.DEFAULT.name));
    }

    @Test
    public void releaseVersionNotSupported(Path base) throws Exception {
        doTestNoSource(base, "error: release version 99999999 not supported",
                "--release 99999999");
    }

    // taken from former test: tools/javac/options/release/ReleaseOptionClashes
    @Test
    public void releaseAndBootclasspath(Path base) throws Exception {
        doTestNoSource(base, "error: option --boot-class-path cannot be used together with --release",
                String.format("--release %s -bootclasspath any", Source.DEFAULT.name));
        doTestNoSource(base, "error: option -Xbootclasspath: cannot be used together with --release",
                String.format("--release %s -Xbootclasspath:any", Source.DEFAULT.name));
        doTestNoSource(base, "error: option -Xbootclasspath/p: cannot be used together with --release",
                String.format("--release %s -Xbootclasspath/p:any", Source.DEFAULT.name));
        doTestNoSource(base, "error: option -endorseddirs cannot be used together with --release",
                String.format("--release %s -endorseddirs any", Source.DEFAULT.name));
        doTestNoSource(base, "error: option -extdirs cannot be used together with --release",
                String.format("--release %s -extdirs any", Source.DEFAULT.name));
        doTestNoSource(base, "error: option --source cannot be used together with --release",
                String.format("--release %s -source %s", Source.MIN.name, Source.DEFAULT.name));
        doTestNoSource(base, "error: option --target cannot be used together with --release",
                String.format("--release %s -target %s", Source.MIN.name, Source.DEFAULT.name));
        doTestNoSource(base, "error: option --system cannot be used together with --release",
                String.format("--release %s --system none", Source.DEFAULT.name));
        doTestNoSource(base, "error: option --upgrade-module-path cannot be used together with --release",
                String.format("--release %s --upgrade-module-path any", Source.DEFAULT.name));
    }

    @Test
    public void consistentSystemOptionHandlingWithAnEmptyDirectory(Path base) throws Exception {
        tb.createDirectories(base);
        doTestNoSource(base, "error: illegal argument for --system: %s".formatted(base), String.format("--system %s", base));
    }

    @Test
    public void consistentSystemOptionHandlingWithLibJrtFsJar(Path base) throws Exception {
        tb.createDirectories(base);
        tb.writeFile(base.resolve("lib").resolve("jrt-fs.jar"), "this is not a JAR file");
        doTestNoSource(base, "error: illegal argument for --system: %s".formatted(base), String.format("--system %s", base));
    }

    @Test
    public void consistentSystemOptionHandlingWithLibModules(Path base) throws Exception {
        tb.createDirectories(base);
        tb.writeFile(base.resolve("lib").resolve("modules"), "this is not a modules file");
        doTestNoSource(base, "error: illegal argument for --system: %s".formatted(base), String.format("--system %s", base));
    }

    @Test
    public void consistentSystemOptionHandlingWithAlmostValidLibEntries(Path base) throws Exception {
        tb.createDirectories(base);
        tb.writeFile(base.resolve("lib").resolve("jrt-fs.jar"), "this is not a JAR file");
        tb.writeFile(base.resolve("lib").resolve("modules"), "this is not a modules file");
        doTestNoSource(base, "error: no source files", String.format("--system %s", base));
    }

    void doTest(Path base, String output, String options) throws Exception {
        Path src = base.resolve("src");
        tb.writeJavaFiles(src, "class Dummy { }");
        String log = new JavacTask(tb, Task.Mode.CMDLINE)
                .spaceSeparatedOptions(options)
                .files(findJavaFiles(src))
                .run(Task.Expect.FAIL)
                .writeAll()
                .getOutput(Task.OutputKind.DIRECT);
        Assert.check(log.startsWith(output), String.format("expected:\n%s\nfound:\n%s", output, log));
    }

    void doTestNoSource(Path base, String output, String options) throws Exception {
        String log = new JavacTask(tb, Task.Mode.CMDLINE)
                .spaceSeparatedOptions(options)
                .run(Task.Expect.FAIL)
                .writeAll()
                .getOutput(Task.OutputKind.DIRECT);
        Assert.check(log.startsWith(output), String.format("expected:\n%s\nfound:\n%s", output, log));
    }
}