ProfileOptionTest.java revision 3822:d8766c39123a
1231990Smp/*
259243Sobrien * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
359243Sobrien * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
459243Sobrien *
559243Sobrien * This code is free software; you can redistribute it and/or modify it
659243Sobrien * under the terms of the GNU General Public License version 2 only, as
759243Sobrien * published by the Free Software Foundation.
859243Sobrien *
959243Sobrien * This code is distributed in the hope that it will be useful, but WITHOUT
1059243Sobrien * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
1159243Sobrien * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
1259243Sobrien * version 2 for more details (a copy is included in the LICENSE file that
1359243Sobrien * accompanied this code).
1459243Sobrien *
1559243Sobrien * You should have received a copy of the GNU General Public License version
1659243Sobrien * 2 along with this work; if not, write to the Free Software Foundation,
17100616Smp * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
1859243Sobrien *
1959243Sobrien * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2059243Sobrien * or visit www.oracle.com if you need additional information or have any
2159243Sobrien * questions.
2259243Sobrien */
2359243Sobrien
2459243Sobrien/*
2559243Sobrien * @test
2659243Sobrien * @bug 8004182 8028545
2759243Sobrien * @summary Add support for profiles in javac
2859243Sobrien * @modules java.desktop
2959243Sobrien *          java.sql.rowset
3059243Sobrien *          jdk.compiler/com.sun.tools.javac.api
3159243Sobrien *          jdk.compiler/com.sun.tools.javac.jvm
3259243Sobrien *          jdk.security.auth
3359243Sobrien */
3459243Sobrien
3559243Sobrienimport java.io.PrintWriter;
3659243Sobrienimport java.io.StringWriter;
3759243Sobrienimport java.lang.annotation.Annotation;
38145479Smpimport java.lang.annotation.Retention;
39167465Smpimport java.lang.annotation.RetentionPolicy;
40145479Smpimport java.lang.reflect.InvocationTargetException;
41145479Smpimport java.lang.reflect.Method;
42145479Smpimport java.net.URI;
43100616Smpimport java.util.ArrayList;
44145479Smpimport java.util.Arrays;
45145479Smpimport java.util.Collections;
46145479Smpimport java.util.EnumMap;
47100616Smpimport java.util.List;
48100616Smpimport java.util.Map;
49145479Smp
50145479Smpimport javax.tools.Diagnostic;
51145479Smpimport javax.tools.DiagnosticCollector;
52145479Smpimport javax.tools.JavaCompiler;
53145479Smpimport javax.tools.JavaFileObject;
54145479Smpimport javax.tools.SimpleJavaFileObject;
55145479Smpimport javax.tools.StandardJavaFileManager;
56145479Smp
5759243Sobrienimport com.sun.source.util.JavacTask;
5859243Sobrienimport com.sun.tools.javac.api.JavacTool;
5959243Sobrienimport com.sun.tools.javac.jvm.Profile;
6069408Sacheimport com.sun.tools.javac.jvm.Target;
6159243Sobrien
6259243Sobrien
6369408Sachepublic class ProfileOptionTest {
6459243Sobrien    public static void main(String... args) throws Exception {
6559243Sobrien        new ProfileOptionTest().run();
6659243Sobrien    }
6759243Sobrien
6859243Sobrien    private final JavaCompiler javac = JavacTool.create();
6959243Sobrien    private final StandardJavaFileManager fm = javac.getStandardFileManager(null, null, null);
7059243Sobrien
71145479Smp
7259243Sobrien    // ---------- Test cases, invoked reflectively via run. ----------
7369408Sache
7459243Sobrien    @Test
7559243Sobrien    void testInvalidProfile_API() throws Exception {
76167465Smp        JavaFileObject fo = new StringJavaFileObject("Test.java", "class Test { }");
7769408Sache        String badName = "foo";
78231990Smp        List<String> opts = Arrays.asList("--release", "8", "-profile", badName);
79231990Smp        StringWriter sw = new StringWriter();
80231990Smp        try {
81231990Smp            JavacTask task = (JavacTask) javac.getTask(sw, fm, null, opts, null,
8259243Sobrien                Arrays.asList(fo));
8359243Sobrien            throw new Exception("expected exception not thrown");
8459243Sobrien        } catch (IllegalArgumentException e) {
8559243Sobrien            // expected
8659243Sobrien        }
8759243Sobrien    }
8859243Sobrien
8959243Sobrien    @Test
9059243Sobrien    void testInvalidProfile_CommandLine() throws Exception {
9159243Sobrien        String badName = "foo";
9259243Sobrien        String[] opts = { "--release", "8", "-profile", badName };
93231990Smp        StringWriter sw = new StringWriter();
94231990Smp        PrintWriter pw = new PrintWriter(sw);
9559243Sobrien        int rc = com.sun.tools.javac.Main.compile(opts, pw);
96167465Smp
97145479Smp        // sadly, command line errors are not (yet?) reported to
98231990Smp        // the diag listener
99231990Smp        String out = sw.toString();
100231990Smp        if (!out.isEmpty())
101145479Smp            System.err.println(out.trim());
102231990Smp
103145479Smp        if (!out.contains("invalid profile: " + badName)) {
104145479Smp            error("expected message not found");
105145479Smp        }
106145479Smp    }
107231990Smp
108145479Smp    @Test
10959243Sobrien    void testTargetProfileCombinations() throws Exception {
11059243Sobrien        JavaFileObject fo = new StringJavaFileObject("Test.java", "class Test { }");
111145479Smp        for (Target t: Target.values()) {
112145479Smp            switch (t) {
113145479Smp                case JDK1_1:
114145479Smp                case JDK1_2:
115145479Smp                case JDK1_3:
11659243Sobrien                case JDK1_4:
11759243Sobrien                case JDK1_5: // not supported
11859243Sobrien                    continue;
11959243Sobrien            }
120145479Smp
121145479Smp            for (Profile p: Profile.values()) {
122145479Smp                List<String> opts = new ArrayList<>();
123145479Smp                opts.addAll(Arrays.asList("-source", t.name, "-target", t.name));
12459243Sobrien                opts.add("-Xlint:-options"); // don't warn about no -bootclasspath
125145479Smp                if (p != Profile.DEFAULT)
12659243Sobrien                    opts.addAll(Arrays.asList("-profile", p.name));
127231990Smp
128231990Smp                IllegalStateException ise;
129231990Smp                StringWriter sw = new StringWriter();
13059243Sobrien                try {
13159243Sobrien                    JavacTask task = (JavacTask) javac.getTask(sw, fm, null, opts, null,
132231990Smp                            Arrays.asList(fo));
133231990Smp                    task.analyze();
134195609Smp                    ise = null;
135195609Smp                } catch (IllegalStateException e) {
136195609Smp                    ise = e;
13759243Sobrien                }
13859243Sobrien
13959243Sobrien                // sadly, command line errors are not (yet?) reported to
14059243Sobrien                // the diag listener
141131962Smp                String out = sw.toString();
142100616Smp                if (!out.isEmpty())
143100616Smp                    System.err.println(out.trim());
144131962Smp
145131962Smp                switch (t) {
146131962Smp                    case JDK1_8:
147131962Smp                        if (ise != null)
148100616Smp                            error("unexpected exception from compiler: " + ise);
14959243Sobrien                        break;
150100616Smp                    case JDK1_9:
15159243Sobrien                        if (p == Profile.DEFAULT)
15259243Sobrien                            break;
15359243Sobrien                        if (ise == null)
15459243Sobrien                            error("IllegalStateException not thrown as expected");
15559243Sobrien                        else if (!ise.getMessage().contains("option -profile " +
15659243Sobrien                                "not allowed with target " + t.name)) {
15759243Sobrien                            error("exception not thrown as expected: " + ise);
15859243Sobrien                        }
15961524Sobrien                        break;
16059243Sobrien                    default:
16161524Sobrien                        if (p == Profile.DEFAULT)
16259243Sobrien                            break;
16359243Sobrien                        if (ise == null)
16461524Sobrien                            error("IllegalStateException not thrown as expected");
16559243Sobrien                        else if (!ise.getMessage().contains("profile " + p.name
16659243Sobrien                                    + " is not valid for target release " + t.name)) {
16759243Sobrien                            error("exception not thrown as expected: " + ise);
16859243Sobrien                        }
16959243Sobrien                        break;
17059243Sobrien                }
17159243Sobrien            }
17259243Sobrien        }
17359243Sobrien    }
17459243Sobrien
17559243Sobrien    @Test
17659243Sobrien    void testClassesInProfiles() throws Exception {
17759243Sobrien        for (Profile p: Profile.values()) {
17859243Sobrien            for (Map.Entry<Profile, List<JavaFileObject>> e: testClasses.entrySet()) {
17959243Sobrien                for (JavaFileObject fo: e.getValue()) {
18059243Sobrien                    DiagnosticCollector<JavaFileObject> dl =
18159243Sobrien                            new DiagnosticCollector<JavaFileObject>();
18259243Sobrien                    List<String> opts = (p == Profile.DEFAULT)
18359243Sobrien                            ? Collections.<String>emptyList()
18459243Sobrien                            : Arrays.asList("--release", "8", "-profile", p.name);
18559243Sobrien                    JavacTask task = (JavacTask) javac.getTask(null, fm, dl, opts, null,
18659243Sobrien                            Arrays.asList(fo));
18759243Sobrien                    task.analyze();
18859243Sobrien
18959243Sobrien                    List<String> expectDiagCodes = new ArrayList<>();
19059243Sobrien                    if (fo.getName().equals("TPolicyFile.java")) {
19159243Sobrien                        expectDiagCodes.add("compiler.warn.has.been.deprecated.for.removal");
19259243Sobrien                    }
19359243Sobrien
19459243Sobrien                    if (p.value < e.getKey().value) {
19559243Sobrien                        expectDiagCodes.add("compiler.err.not.in.profile");
196145479Smp                    }
19759243Sobrien
19859243Sobrien                    checkDiags(opts + " " + fo.getName(), dl.getDiagnostics(), expectDiagCodes);
19959243Sobrien                }
20059243Sobrien            }
20159243Sobrien        }
20259243Sobrien    }
20359243Sobrien
20459243Sobrien    Map<Profile, List<JavaFileObject>> testClasses =
20559243Sobrien            new EnumMap<Profile, List<JavaFileObject>>(Profile.class);
20659243Sobrien
20759243Sobrien    void initTestClasses() {
20859243Sobrien        // The following table assumes the existence of specific classes
20959243Sobrien        // in specific profiles, as defined in the Java SE 8 spec.
21059243Sobrien        init(Profile.COMPACT1,
21159243Sobrien                java.lang.String.class);
21259243Sobrien
21359243Sobrien        init(Profile.COMPACT2,
21459243Sobrien                javax.xml.XMLConstants.class);
21559243Sobrien
21659243Sobrien        //init(Profile.COMPACT3,
21759243Sobrien        //        javax.sql.rowset.Predicate.class,
21859243Sobrien        //        com.sun.security.auth.PolicyFile.class); // specifically included in 3
21959243Sobrien
22059243Sobrien        init(Profile.COMPACT3,
22169408Sache                javax.sql.rowset.Predicate.class);
22259243Sobrien
22359243Sobrien        init(Profile.DEFAULT,
22459243Sobrien                java.beans.BeanInfo.class);
22569408Sache    }
22659243Sobrien
22759243Sobrien    void init(Profile p, Class<?>... classes) {
22883098Smp        List<JavaFileObject> srcs = new ArrayList<JavaFileObject>();
22959243Sobrien        for (Class<?> c: classes) {
23059243Sobrien            String name = "T" + c.getSimpleName();
23159243Sobrien            String src =
23259243Sobrien                    "class T" + name + "{" + "\n" +
23383098Smp                    "    Class<?> c = " + c.getName() + ".class;\n" +
23459243Sobrien                    "}";
235231990Smp            srcs.add(new StringJavaFileObject(name + ".java", src));
236231990Smp        }
237231990Smp        testClasses.put(p, srcs);
238231990Smp    }
239231990Smp
24059243Sobrien    void checkDiags(String msg, List<Diagnostic<? extends JavaFileObject>> diags, List<String> expectDiagCodes) {
24159243Sobrien        System.err.print(msg);
24259243Sobrien        if (diags.isEmpty())
24359243Sobrien            System.err.println(" OK");
24459243Sobrien        else {
24559243Sobrien            System.err.println();
24659243Sobrien            System.err.println(diags);
24759243Sobrien        }
24859243Sobrien
24959243Sobrien        List<String> foundDiagCodes = new ArrayList<String>();
25059243Sobrien        for (Diagnostic<? extends JavaFileObject> d: diags)
25169408Sache            foundDiagCodes.add(d.getCode());
25259243Sobrien
25369408Sache        if (!foundDiagCodes.equals(expectDiagCodes)) {
25459243Sobrien            System.err.println("Found diag codes:    " + foundDiagCodes);
25559243Sobrien            System.err.println("Expected diag codes: " + expectDiagCodes);
25659243Sobrien            error("expected diagnostics not found");
25759243Sobrien        }
25859243Sobrien    }
25969408Sache
26059243Sobrien    /** Marker annotation for test cases. */
26169408Sache    @Retention(RetentionPolicy.RUNTIME)
26259243Sobrien    @interface Test { }
26359243Sobrien
26459243Sobrien    /** Run all test cases. */
26559243Sobrien    void run() throws Exception {
26669408Sache        try {
26759243Sobrien            initTestClasses();
26859243Sobrien
26959243Sobrien            for (Method m: getClass().getDeclaredMethods()) {
27059243Sobrien                Annotation a = m.getAnnotation(Test.class);
27159243Sobrien                if (a != null) {
27259243Sobrien                    System.err.println(m.getName());
27359243Sobrien                    try {
27459243Sobrien                        m.invoke(this, new Object[] { });
27559243Sobrien                    } catch (InvocationTargetException e) {
27659243Sobrien                        Throwable cause = e.getCause();
27759243Sobrien                        throw (cause instanceof Exception) ? ((Exception) cause) : e;
27859243Sobrien                    }
27969408Sache                    System.err.println();
28059243Sobrien                }
28159243Sobrien            }
28259243Sobrien
28359243Sobrien            if (errors > 0)
28459243Sobrien                throw new Exception(errors + " errors occurred");
28559243Sobrien        } finally {
28659243Sobrien            fm.close();
28759243Sobrien        }
28859243Sobrien    }
28959243Sobrien
29059243Sobrien    void error(String msg) {
29159243Sobrien        System.err.println("Error: " + msg);
292231990Smp        errors++;
29359243Sobrien    }
29459243Sobrien
29559243Sobrien    int errors;
29659243Sobrien
29759243Sobrien    private static class StringJavaFileObject extends SimpleJavaFileObject {
29859243Sobrien        StringJavaFileObject(String name, String text) {
29969408Sache            super(URI.create(name), JavaFileObject.Kind.SOURCE);
30059243Sobrien            this.text = text;
30159243Sobrien        }
30259243Sobrien        @Override
30359243Sobrien        public CharSequence getCharContent(boolean b) {
30459243Sobrien            return text;
30569408Sache        }
30659243Sobrien        private String text;
30759243Sobrien    }
30859243Sobrien}
30959243Sobrien