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