comparison graal/com.oracle.jvmci.runtime.test/src/com/oracle/jvmci/runtime/test/TestResolvedJavaMethod.java @ 21663:381ab4105afe

moved com.oracle.graal.java.test to com.oracle.jvmci.runtime.test
author Doug Simon <doug.simon@oracle.com>
date Tue, 02 Jun 2015 15:15:58 +0200
parents graal/com.oracle.graal.java.test/src/com/oracle/graal/java/test/TestResolvedJavaMethod.java@36cf15e3219e
children
comparison
equal deleted inserted replaced
21662:b45e0f791465 21663:381ab4105afe
1 /*
2 * Copyright (c) 2012, 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 package com.oracle.jvmci.runtime.test;
24
25 import com.oracle.jvmci.meta.ExceptionHandler;
26 import com.oracle.jvmci.meta.ResolvedJavaMethod;
27 import com.oracle.jvmci.meta.ConstantPool;
28 import static org.junit.Assert.*;
29
30 import java.lang.annotation.*;
31 import java.lang.reflect.*;
32 import java.util.*;
33
34 import org.junit.*;
35
36 /**
37 * Tests for {@link ResolvedJavaMethod}.
38 */
39 public class TestResolvedJavaMethod extends MethodUniverse {
40
41 public TestResolvedJavaMethod() {
42 }
43
44 /**
45 * @see ResolvedJavaMethod#getCode()
46 */
47 @Test
48 public void getCodeTest() {
49 for (Map.Entry<Method, ResolvedJavaMethod> e : methods.entrySet()) {
50 ResolvedJavaMethod m = e.getValue();
51 byte[] code = m.getCode();
52 if (code == null) {
53 assertTrue(m.getCodeSize() == 0);
54 } else {
55 if (m.isAbstract()) {
56 assertTrue(code.length == 0);
57 } else if (!m.isNative()) {
58 assertTrue(code.length > 0);
59 }
60 }
61 }
62 }
63
64 /**
65 * @see ResolvedJavaMethod#getCodeSize()
66 */
67 @Test
68 public void getCodeSizeTest() {
69 for (Map.Entry<Method, ResolvedJavaMethod> e : methods.entrySet()) {
70 ResolvedJavaMethod m = e.getValue();
71 int codeSize = m.getCodeSize();
72 if (m.isAbstract()) {
73 assertTrue(codeSize == 0);
74 } else if (!m.isNative()) {
75 assertTrue(codeSize > 0);
76 }
77 }
78 }
79
80 @Test
81 public void getModifiersTest() {
82 for (Map.Entry<Method, ResolvedJavaMethod> e : methods.entrySet()) {
83 ResolvedJavaMethod m = e.getValue();
84 int expected = e.getKey().getModifiers() & Modifier.methodModifiers();
85 int actual = m.getModifiers();
86 assertEquals(expected, actual);
87 }
88 }
89
90 /**
91 * @see ResolvedJavaMethod#isClassInitializer()
92 */
93 @Test
94 public void isClassInitializerTest() {
95 for (Map.Entry<Method, ResolvedJavaMethod> e : methods.entrySet()) {
96 // Class initializers are hidden from reflection
97 ResolvedJavaMethod m = e.getValue();
98 assertFalse(m.isClassInitializer());
99 }
100 for (Map.Entry<Constructor<?>, ResolvedJavaMethod> e : constructors.entrySet()) {
101 ResolvedJavaMethod m = e.getValue();
102 assertFalse(m.isClassInitializer());
103 }
104 }
105
106 @Test
107 public void isConstructorTest() {
108 for (Map.Entry<Method, ResolvedJavaMethod> e : methods.entrySet()) {
109 ResolvedJavaMethod m = e.getValue();
110 assertFalse(m.isConstructor());
111 }
112 for (Map.Entry<Constructor<?>, ResolvedJavaMethod> e : constructors.entrySet()) {
113 ResolvedJavaMethod m = e.getValue();
114 assertTrue(m.isConstructor());
115 }
116 }
117
118 @Test
119 public void isSyntheticTest() {
120 for (Map.Entry<Method, ResolvedJavaMethod> e : methods.entrySet()) {
121 ResolvedJavaMethod m = e.getValue();
122 assertEquals(e.getKey().isSynthetic(), m.isSynthetic());
123 }
124 for (Map.Entry<Constructor<?>, ResolvedJavaMethod> e : constructors.entrySet()) {
125 ResolvedJavaMethod m = e.getValue();
126 assertEquals(e.getKey().isSynthetic(), m.isSynthetic());
127 }
128 }
129
130 @Test
131 public void isSynchronizedTest() {
132 for (Map.Entry<Method, ResolvedJavaMethod> e : methods.entrySet()) {
133 ResolvedJavaMethod m = e.getValue();
134 assertEquals(Modifier.isSynchronized(e.getKey().getModifiers()), m.isSynchronized());
135 }
136 for (Map.Entry<Constructor<?>, ResolvedJavaMethod> e : constructors.entrySet()) {
137 ResolvedJavaMethod m = e.getValue();
138 assertEquals(Modifier.isSynchronized(e.getKey().getModifiers()), m.isSynchronized());
139 }
140 }
141
142 @Test
143 public void canBeStaticallyBoundTest() {
144 for (Map.Entry<Method, ResolvedJavaMethod> e : methods.entrySet()) {
145 ResolvedJavaMethod m = e.getValue();
146 assertEquals(m.canBeStaticallyBound(), canBeStaticallyBound(e.getKey()));
147 }
148 for (Map.Entry<Constructor<?>, ResolvedJavaMethod> e : constructors.entrySet()) {
149 ResolvedJavaMethod m = e.getValue();
150 assertEquals(m.canBeStaticallyBound(), canBeStaticallyBound(e.getKey()));
151 }
152 }
153
154 private static boolean canBeStaticallyBound(Member method) {
155 int modifiers = method.getModifiers();
156 return (Modifier.isFinal(modifiers) || Modifier.isPrivate(modifiers) || Modifier.isStatic(modifiers) || Modifier.isFinal(method.getDeclaringClass().getModifiers())) &&
157 !Modifier.isAbstract(modifiers);
158 }
159
160 private static String methodWithExceptionHandlers(String p1, Object o2) {
161 try {
162 return p1.substring(100) + o2.toString();
163 } catch (IndexOutOfBoundsException e) {
164 e.printStackTrace();
165 } catch (NullPointerException e) {
166 e.printStackTrace();
167 } catch (RuntimeException e) {
168 e.printStackTrace();
169 }
170 return null;
171 }
172
173 @Test
174 public void getExceptionHandlersTest() throws NoSuchMethodException {
175 ResolvedJavaMethod method = metaAccess.lookupJavaMethod(getClass().getDeclaredMethod("methodWithExceptionHandlers", String.class, Object.class));
176 ExceptionHandler[] handlers = method.getExceptionHandlers();
177 assertNotNull(handlers);
178 assertEquals(handlers.length, 3);
179 handlers[0].getCatchType().equals(metaAccess.lookupJavaType(IndexOutOfBoundsException.class));
180 handlers[1].getCatchType().equals(metaAccess.lookupJavaType(NullPointerException.class));
181 handlers[2].getCatchType().equals(metaAccess.lookupJavaType(RuntimeException.class));
182 }
183
184 private static String nullPointerExceptionOnFirstLine(Object o, String ignored) {
185 return o.toString() + ignored;
186 }
187
188 @Test
189 public void asStackTraceElementTest() throws NoSuchMethodException {
190 try {
191 nullPointerExceptionOnFirstLine(null, "ignored");
192 Assert.fail("should not reach here");
193 } catch (NullPointerException e) {
194 StackTraceElement expected = e.getStackTrace()[0];
195 ResolvedJavaMethod method = metaAccess.lookupJavaMethod(getClass().getDeclaredMethod("nullPointerExceptionOnFirstLine", Object.class, String.class));
196 StackTraceElement actual = method.asStackTraceElement(0);
197 assertEquals(expected, actual);
198 }
199 }
200
201 @Test
202 public void getConstantPoolTest() {
203 for (Map.Entry<Method, ResolvedJavaMethod> e : methods.entrySet()) {
204 ResolvedJavaMethod m = e.getValue();
205 ConstantPool cp = m.getConstantPool();
206 assertTrue(cp.length() > 0);
207 }
208 }
209
210 @Test(timeout = 1000L)
211 public void getAnnotationTest() throws NoSuchMethodException {
212 ResolvedJavaMethod method = metaAccess.lookupJavaMethod(getClass().getDeclaredMethod("getAnnotationTest"));
213 Test annotation = method.getAnnotation(Test.class);
214 assertNotNull(annotation);
215 assertEquals(1000L, annotation.timeout());
216 }
217
218 @Test(timeout = 1000L)
219 public void getAnnotationsTest() throws NoSuchMethodException {
220 ResolvedJavaMethod method = metaAccess.lookupJavaMethod(getClass().getDeclaredMethod("getAnnotationsTest"));
221 Annotation[] annotations = method.getAnnotations();
222 assertNotNull(annotations);
223 assertEquals(1, annotations.length);
224 assertEquals(1000L, ((Test) annotations[0]).timeout());
225 }
226
227 @Retention(RetentionPolicy.RUNTIME)
228 @Target(ElementType.PARAMETER)
229 @interface NonNull {
230 }
231
232 @Retention(RetentionPolicy.RUNTIME)
233 @Target(ElementType.PARAMETER)
234 @interface Special {
235 }
236
237 private static native void methodWithAnnotatedParameters(@NonNull HashMap<String, String> p1, @Special @NonNull Class<? extends Annotation> p2);
238
239 @Test
240 public void getParameterAnnotationsTest() throws NoSuchMethodException {
241 ResolvedJavaMethod method = metaAccess.lookupJavaMethod(getClass().getDeclaredMethod("methodWithAnnotatedParameters", HashMap.class, Class.class));
242 Annotation[][] annotations = method.getParameterAnnotations();
243 assertEquals(2, annotations.length);
244 assertEquals(1, annotations[0].length);
245 assertEquals(NonNull.class, annotations[0][0].annotationType());
246 assertEquals(2, annotations[1].length);
247 assertEquals(Special.class, annotations[1][0].annotationType());
248 assertEquals(NonNull.class, annotations[1][1].annotationType());
249 }
250
251 @Test
252 public void getGenericParameterTypesTest() throws NoSuchMethodException {
253 ResolvedJavaMethod method = metaAccess.lookupJavaMethod(getClass().getDeclaredMethod("methodWithAnnotatedParameters", HashMap.class, Class.class));
254 Type[] genericParameterTypes = method.getGenericParameterTypes();
255 assertEquals(2, genericParameterTypes.length);
256 assertEquals("java.util.HashMap<java.lang.String, java.lang.String>", genericParameterTypes[0].toString());
257 assertEquals("java.lang.Class<? extends java.lang.annotation.Annotation>", genericParameterTypes[1].toString());
258 }
259
260 @Test
261 public void getMaxLocalsTest() throws NoSuchMethodException {
262 ResolvedJavaMethod method1 = metaAccess.lookupJavaMethod(getClass().getDeclaredMethod("methodWithAnnotatedParameters", HashMap.class, Class.class));
263 ResolvedJavaMethod method2 = metaAccess.lookupJavaMethod(getClass().getDeclaredMethod("nullPointerExceptionOnFirstLine", Object.class, String.class));
264 assertEquals(0, method1.getMaxLocals());
265 assertEquals(2, method2.getMaxLocals());
266
267 }
268
269 @Test
270 public void getMaxStackSizeTest() throws NoSuchMethodException {
271 ResolvedJavaMethod method1 = metaAccess.lookupJavaMethod(getClass().getDeclaredMethod("methodWithAnnotatedParameters", HashMap.class, Class.class));
272 ResolvedJavaMethod method2 = metaAccess.lookupJavaMethod(getClass().getDeclaredMethod("nullPointerExceptionOnFirstLine", Object.class, String.class));
273 assertEquals(0, method1.getMaxStackSize());
274 // some versions of javac produce bytecode with a stacksize of 2 for this method
275 // JSR 292 also sometimes need one more stack slot
276 int method2StackSize = method2.getMaxStackSize();
277 assertTrue(2 <= method2StackSize && method2StackSize <= 4);
278 }
279
280 @Test
281 public void isDefaultTest() {
282 for (Map.Entry<Method, ResolvedJavaMethod> e : methods.entrySet()) {
283 ResolvedJavaMethod m = e.getValue();
284 assertEquals(e.getKey().isDefault(), m.isDefault());
285 }
286 for (Map.Entry<Constructor<?>, ResolvedJavaMethod> e : constructors.entrySet()) {
287 ResolvedJavaMethod m = e.getValue();
288 assertFalse(m.isDefault());
289 }
290 }
291
292 @Test
293 public void hasReceiverTest() {
294 for (Map.Entry<Method, ResolvedJavaMethod> e : methods.entrySet()) {
295 ResolvedJavaMethod m = e.getValue();
296 assertTrue(m.hasReceiver() != Modifier.isStatic(e.getKey().getModifiers()));
297 }
298 for (Map.Entry<Constructor<?>, ResolvedJavaMethod> e : constructors.entrySet()) {
299 ResolvedJavaMethod m = e.getValue();
300 assertTrue(m.hasReceiver());
301 }
302 }
303
304 @Test
305 public void hasBytecodesTest() {
306 for (Map.Entry<Method, ResolvedJavaMethod> e : methods.entrySet()) {
307 ResolvedJavaMethod m = e.getValue();
308 assertTrue(m.hasBytecodes() == (m.isConcrete() && !m.isNative()));
309 }
310 for (Map.Entry<Constructor<?>, ResolvedJavaMethod> e : constructors.entrySet()) {
311 ResolvedJavaMethod m = e.getValue();
312 assertTrue(m.hasBytecodes());
313 }
314 }
315
316 @Test
317 public void isJavaLangObjectInitTest() throws NoSuchMethodException {
318 ResolvedJavaMethod method = metaAccess.lookupJavaMethod(Object.class.getConstructor());
319 assertTrue(method.isJavaLangObjectInit());
320 for (Map.Entry<Method, ResolvedJavaMethod> e : methods.entrySet()) {
321 ResolvedJavaMethod m = e.getValue();
322 assertFalse(m.isJavaLangObjectInit());
323 }
324 for (Map.Entry<Constructor<?>, ResolvedJavaMethod> e : constructors.entrySet()) {
325 ResolvedJavaMethod m = e.getValue();
326 Constructor<?> key = e.getKey();
327 if (key.getDeclaringClass() == Object.class && key.getParameters().length == 0) {
328 assertTrue(m.isJavaLangObjectInit());
329 } else {
330 assertFalse(m.isJavaLangObjectInit());
331 }
332 }
333 }
334
335 private Method findTestMethod(Method apiMethod) {
336 String testName = apiMethod.getName() + "Test";
337 for (Method m : getClass().getDeclaredMethods()) {
338 if (m.getName().equals(testName) && m.getAnnotation(Test.class) != null) {
339 return m;
340 }
341 }
342 return null;
343 }
344
345 // @formatter:off
346 private static final String[] untestedApiMethods = {
347 "invoke",
348 "newInstance",
349 "getDeclaringClass",
350 "getEncoding",
351 "getProfilingInfo",
352 "reprofile",
353 "getCompilerStorage",
354 "canBeInlined",
355 "shouldBeInlined",
356 "getLineNumberTable",
357 "getLocalVariableTable",
358 "isInVirtualMethodTable",
359 "toParameterTypes",
360 "getParameterAnnotation",
361 "getSpeculationLog",
362 "$jacocoInit"
363 };
364 // @formatter:on
365
366 /**
367 * Ensures that any new methods added to {@link ResolvedJavaMethod} either have a test written
368 * for them or are added to {@link #untestedApiMethods}.
369 */
370 @Test
371 public void testCoverage() {
372 Set<String> known = new HashSet<>(Arrays.asList(untestedApiMethods));
373 for (Method m : ResolvedJavaMethod.class.getDeclaredMethods()) {
374 if (findTestMethod(m) == null) {
375 assertTrue("test missing for " + m, known.contains(m.getName()));
376 } else {
377 assertFalse("test should be removed from untestedApiMethods" + m, known.contains(m.getName()));
378 }
379 }
380 }
381 }