1/*
2 * Copyright (c) 2015, 2016, 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
26 * @bug 8136421
27 * @requires vm.jvmci
28 * @library / /test/lib
29 * @library ../common/patches
30 * @modules java.base/jdk.internal.misc
31 * @modules jdk.internal.vm.ci/jdk.vm.ci.hotspot
32 * @build jdk.internal.vm.ci/jdk.vm.ci.hotspot.CompilerToVMHelper
33 * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI
34 *                   -Djvmci.Compiler=null
35 *                   compiler.jvmci.compilerToVM.LookupTypeTest
36 */
37
38package compiler.jvmci.compilerToVM;
39
40import compiler.jvmci.common.testcases.DoNotExtendClass;
41import compiler.jvmci.common.testcases.MultiSubclassedClass;
42import compiler.jvmci.common.testcases.SingleSubclass;
43import jdk.test.lib.Asserts;
44import jdk.test.lib.Utils;
45import jdk.vm.ci.hotspot.CompilerToVMHelper;
46import jdk.vm.ci.hotspot.HotSpotResolvedObjectType;
47
48import java.util.HashSet;
49import java.util.Set;
50
51public class LookupTypeTest {
52    public static void main(String args[]) {
53        LookupTypeTest test = new LookupTypeTest();
54        for (TestCase tcase : createTestCases()) {
55            test.runTest(tcase);
56        }
57    }
58
59    private static Set<TestCase> createTestCases() {
60        Set<TestCase> result = new HashSet<>();
61        // a primitive class
62        result.add(new TestCase(Utils.toJVMTypeSignature(int.class),
63                LookupTypeTest.class, true, false, InternalError.class));
64        // lookup not existing class
65        result.add(new TestCase("Lsome_not_existing;", LookupTypeTest.class,
66                true, false, ClassNotFoundException.class));
67        // lookup invalid classname
68        result.add(new TestCase("L!@#$%^&**()[]{}?;", LookupTypeTest.class,
69                true, false, ClassNotFoundException.class));
70        // lookup package private class
71        result.add(new TestCase(
72                "Lcompiler/jvmci/compilerToVM/testcases/PackagePrivateClass;",
73                LookupTypeTest.class, true, false,
74                ClassNotFoundException.class));
75        // lookup usual class with resolve=true
76        result.add(new TestCase(Utils.toJVMTypeSignature(SingleSubclass.class),
77                LookupTypeTest.class, true, true));
78        // lookup usual class with resolve=false
79        result.add(new TestCase(
80                Utils.toJVMTypeSignature(DoNotExtendClass.class),
81                LookupTypeTest.class, false, true));
82        // lookup usual class with null accessor
83        result.add(new TestCase(
84                Utils.toJVMTypeSignature(MultiSubclassedClass.class), null,
85                false, false, NullPointerException.class));
86        return result;
87    }
88
89    private void runTest(TestCase tcase) {
90        System.out.println(tcase);
91        HotSpotResolvedObjectType metaspaceKlass;
92        try {
93            metaspaceKlass = CompilerToVMHelper.lookupType(tcase.className,
94                    tcase.accessing, tcase.resolve);
95        } catch (Throwable t) {
96            Asserts.assertNotNull(tcase.expectedException,
97                    "Assumed no exception, but got " + t);
98            Asserts.assertFalse(tcase.isPositive,
99                    "Got unexpected exception " + t);
100            Asserts.assertEQ(t.getClass(), tcase.expectedException,
101                    "Unexpected exception");
102            // passed
103            return;
104        }
105        if (tcase.expectedException != null) {
106            throw new AssertionError("Expected exception was not thrown: "
107                    + tcase.expectedException.getName());
108        }
109        if (tcase.isPositive) {
110            Asserts.assertNotNull(metaspaceKlass,
111                    "Unexpected null metaspace klass");
112            Asserts.assertEQ(metaspaceKlass.getName(), tcase.className,
113                    "Got unexpected resolved class name");
114        } else {
115            Asserts.assertNull(metaspaceKlass, "Unexpected metaspace klass");
116        }
117    }
118
119    private static class TestCase {
120        public final String className;
121        public final Class<?> accessing;
122        public final boolean resolve;
123        public final boolean isPositive;
124        public final Class<? extends Throwable> expectedException;
125
126        public TestCase(String className, Class<?> accessing, boolean resolve,
127                boolean isPositive,
128                Class<? extends Throwable> expectedException) {
129            this.className = className;
130            this.accessing = accessing;
131            this.resolve = resolve;
132            this.isPositive = isPositive;
133            this.expectedException = expectedException;
134        }
135
136        public TestCase(String className, Class<?> accessing, boolean resolve,
137                boolean isPositive) {
138            this.className = className;
139            this.accessing = accessing;
140            this.resolve = resolve;
141            this.isPositive = isPositive;
142            this.expectedException = null;
143        }
144
145        @Override
146        public String toString() {
147            return String.format("CASE: class=%s, accessing=%s,"
148                + " resolve=%s, positive=%s, expectedException=%s", className,
149                accessing, resolve, isPositive, expectedException);
150        }
151    }
152}
153