Mercurial > hg > Members > kono > jpf-core
diff src/tests/gov/nasa/jpf/test/vm/reflection/MethodTest.java @ 0:61d41facf527
initial v8 import (history reset)
author | Peter Mehlitz <Peter.C.Mehlitz@nasa.gov> |
---|---|
date | Fri, 23 Jan 2015 10:14:01 -0800 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/tests/gov/nasa/jpf/test/vm/reflection/MethodTest.java Fri Jan 23 10:14:01 2015 -0800 @@ -0,0 +1,686 @@ +/* + * Copyright (C) 2014, United States Government, as represented by the + * Administrator of the National Aeronautics and Space Administration. + * All rights reserved. + * + * The Java Pathfinder core (jpf-core) platform is licensed under the + * Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package gov.nasa.jpf.test.vm.reflection; + +import gov.nasa.jpf.util.test.TestJPF; + +import java.lang.annotation.Annotation; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +import org.junit.Test; + +public class MethodTest extends TestJPF { + + private double m_data = 42.0; + private Object m_arg; + + static class Boo { + + static int d = 42; + } + + static class Faz { + + static int d = 4200; + + static private int foo (int a){ + return a + 42; + } + } + + static class SupC { + + private int privateMethod() { + return -42; + } + } + + static class SubC extends SupC { + + public int privateMethod() { + return 42; + } + } + + public Boo getBoo() { + return null; + } + + public double foo(int a, double d, String s) { + System.out.printf("in foo( %d, %f, %s)\n", a,d,s); + + assert m_data == 42.0 : "wrong object data"; + assert a == 3 : "wrong int parameter value"; + assert d == 3.33 : "wrong double parameter value"; + assert "Blah".equals(s) : "wrong String parameter value"; + + return 123.456; + } + + @Test + public void testInstanceMethodInvoke() { + if (verifyNoPropertyViolation()) { + MethodTest o = new MethodTest(); + + try { + Class<?> cls = o.getClass(); + Method m = cls.getMethod("foo", int.class, double.class, String.class); + + Object res = m.invoke(o, new Integer(3), new Double(3.33), "Blah"); + double d = ((Double) res).doubleValue(); + System.out.println("foo returned " + d); + + assert d == 123.456 : "wrong return value"; + + } catch (Throwable t) { + t.printStackTrace(); + + assert false : " unexpected exception: " + t; + } + } + } + + public static int harr (int a){ + System.out.printf("in harr(%d)\n", a); + + return a+1; + } + + @Test + public void testStaticMethodInvoke() { + if (verifyNoPropertyViolation()) { + MethodTest o = new MethodTest(); + + try { + Class<?> cls = o.getClass(); + Method m = cls.getMethod("harr", int.class); + + Object res = m.invoke(null, new Integer(41)); + int r = (Integer)res; + System.out.println("harr returned " + r); + + assert r == 42 : "wrong return value"; + + } catch (Throwable t) { + t.printStackTrace(); + + assert false : " unexpected exception: " + t; + } + } + } + + public static void doAlmostNothing(){ + System.out.println("in doAlmostNothing"); + } + + @Test + public void testNoArgStaticMethodInvoke() { + if (verifyNoPropertyViolation()) { + MethodTest o = new MethodTest(); + + try { + Class<?> cls = o.getClass(); + Method m = cls.getMethod("doAlmostNothing"); + + Object res = m.invoke(null, (Object[])null); + System.out.println("doAlmostNothing returned " + res); + + assert res == null : "wrong return value"; + + } catch (Throwable t) { + t.printStackTrace(); + + assert false : " unexpected exception: " + t; + } + } + } + + + + @Test + public void getPrivateMethod() throws NoSuchMethodException { + if (verifyUnhandledException(NoSuchMethodException.class.getName())) { + Integer.class.getMethod("toUnsignedString0", int.class, int.class); // Doesn't matter which class we use. It just needs to be a different class and a private method. + } + } + + private static void privateStaticMethod() { + } + + @Test + public void invokePrivateSameClass() throws NoSuchMethodException, IllegalAccessException, InvocationTargetException { + privateStaticMethod(); // Get rid of IDE warning + + if (verifyNoPropertyViolation()) { + Method m = getClass().getDeclaredMethod("privateStaticMethod"); + + m.invoke(null); + } + } + + @Test + public void invokePrivateOtherClass() throws NoSuchMethodException, IllegalAccessException, InvocationTargetException { + if (verifyUnhandledException(IllegalAccessException.class.getName())) { + Method m = Faz.class.getDeclaredMethod("foo", int.class); + + int res = (Integer)m.invoke(null, 5); + fail("should never get here"); + } + } + + @Test + public void invokePrivateOtherClassAccessible() throws NoSuchMethodException, IllegalAccessException, InvocationTargetException { + if (verifyNoPropertyViolation()) { + Method m = Faz.class.getDeclaredMethod("foo", int.class); + + m.setAccessible(true); + int res = (Integer)m.invoke(null, 5); + assertTrue( res == 47); + } + } + + @Test + public void invokePrivateSuperclass() throws SecurityException, NoSuchMethodException, IllegalAccessException, InvocationTargetException { + if (verifyNoPropertyViolation()) { + Method aMethod = SupC.class.getDeclaredMethod("privateMethod"); + aMethod.setAccessible(true); + assert ((Integer) aMethod.invoke(new SubC()) == -42) : "must call method from superclass"; + } + } + + @Test + public void getMethodCanFindNotify() throws NoSuchMethodException { + if (verifyNoPropertyViolation()) { + Integer.class.getMethod("notify"); + } + } + + @Test + public void getDeclaredMethodCantFindNotify() throws NoSuchMethodException { + if (verifyUnhandledException(NoSuchMethodException.class.getName())) { + Integer.class.getDeclaredMethod("notify"); + } + } + + public void publicMethod() { + } + + @Test + public void invokeWrongThisType() throws NoSuchMethodException, IllegalAccessException, InvocationTargetException { + if (verifyUnhandledException(IllegalArgumentException.class.getName())) { + Method m = getClass().getMethod("publicMethod"); + + m.invoke(new Object()); + } + } + + @Test + public void invokeNullObject() throws NoSuchMethodException, IllegalAccessException, InvocationTargetException { + if (verifyUnhandledException(NullPointerException.class.getName())) { + Method m = getClass().getMethod("publicMethod"); + + m.invoke(null); + } + } + + @Test + public void invokeWrongNumberOfArguments() throws NoSuchMethodException, IllegalAccessException, InvocationTargetException { + if (verifyUnhandledException(IllegalArgumentException.class.getName())) { + Method m = getClass().getMethod("publicMethod"); + + m.invoke(this, 5); + } + } + + @Test + public void invokeWrongArgumentTypeReference() throws NoSuchMethodException, IllegalAccessException, InvocationTargetException { + if (verifyUnhandledException(IllegalArgumentException.class.getName())) { + Method m = getClass().getMethod("boofaz", Boo.class, Faz.class); + + m.invoke(this, new Faz(), new Boo()); + } + } + + public void throwThrowable() throws Throwable { + throw new Throwable("purposeful exception"); + } + + @Test + public void invokeInvocationTargetException() throws NoSuchMethodException, IllegalAccessException, InvocationTargetException { + Class<?> clazz; + Method method; + + if (verifyUnhandledException(InvocationTargetException.class.getName())) { + clazz = getClass(); + method = clazz.getMethod("throwThrowable"); + + method.invoke(this); + } + } + + @Test + public void testReturnType() { + if (verifyNoPropertyViolation()) { + MethodTest o = new MethodTest(); + + try { + Class<?> cls = o.getClass(); + Method m = cls.getMethod("getBoo"); + Class<?> rt = m.getReturnType(); + String s = rt.getName(); + + assert Boo.class.getName().equals(s) : "wrong return type: " + s; + + } catch (Throwable t) { + t.printStackTrace(); + + assert false : " unexpected exception in Method.getReturnType(): " + t; + } + } + } + + public void boofaz(Boo b, Faz f) { + b = null; // Get rid of IDE warning + f = null; + } + + @Test + public void testParameterTypes() { + if (verifyNoPropertyViolation()) { + MethodTest o = new MethodTest(); + + try { + Class<?> cls = o.getClass(); + + for (Method m : cls.getMethods()) { + if (m.getName().equals("boofaz")) { + Class<?>[] pt = m.getParameterTypes(); + + assert Boo.class.getName().equals(pt[0].getName()) : "wrong parameter type 0: " + pt[0].getName(); + assert Faz.class.getName().equals(pt[1].getName()) : "wrong parameter type 1: " + pt[1].getName(); + } + } + + } catch (Throwable t) { + t.printStackTrace(); + + assert false : " unexpected exception in Method.getParameterTypes(): " + t; + } + } + } + + //--- argument value conversion tests + + static final Object[] testArgValues = { + Byte.valueOf((byte) 7), + Short.valueOf((short) 8), + Integer.valueOf(9), + Long.valueOf(10), + Float.valueOf(3.1415f), + Double.valueOf(3.14159), + Boolean.TRUE, + Character.valueOf('w'), + "hello", + null + }; + + static final Object ILLEGAL = new Object(); // we use this to flag an IllegalArgumentException + + private void invokeTest (Method m, Object argValue, Object expected){ + System.out.print(argValue); + System.out.print("=>"); + try { + Object ret = m.invoke(this, argValue); + System.out.println(ret); + if (isJPFRun()) { + assertTrue( ((ret == null) && (expected == null)) || ret.equals(expected)); + } + + } catch (IllegalArgumentException ix){ + System.out.println("ILLEGAL"); + if (isJPFRun()) { + assertTrue( expected == ILLEGAL); + } + + } catch (Throwable t){ + fail("_test invocation failed for value = " + argValue + " with " + t); + } + } + + //--- boolean argument + + boolean _test (boolean v){ + //System.out.println("-- test(boolean) got " + v); + return v; + } + + @Test + public void argTestBoolean() throws NoSuchMethodException { + if (verifyNoPropertyViolation()){ + Method m = MethodTest.class.getDeclaredMethod("_test", boolean.class); + Object[] expected = { // all but Boolean throws + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, Boolean.TRUE, ILLEGAL, ILLEGAL, ILLEGAL + }; + + for (int i=0; i<testArgValues.length; i++){ + invokeTest( m, testArgValues[i], expected[i]); + } + } + } + + //--- byte argument + byte _test(byte v){ + //System.out.println("-- test(long) got " + v); + return v; + } + + @Test + public void argTestByte() throws NoSuchMethodException { + if (verifyNoPropertyViolation()){ + Method m = MethodTest.class.getDeclaredMethod("_test", byte.class); + Object[] expected = { // all but byte throws + Byte.valueOf((byte)7), ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL + }; + + for (int i=0; i<testArgValues.length; i++){ + invokeTest( m, testArgValues[i], expected[i]); + } + } + } + + //--- short argument + short _test(short v){ + //System.out.println("-- test(short) got " + v); + return v; + } + + @Test + public void argTestShort() throws NoSuchMethodException { + if (verifyNoPropertyViolation()){ + Method m = MethodTest.class.getDeclaredMethod("_test", short.class); + Object[] expected = { // all but byte and short throws + Short.valueOf((short)7), Short.valueOf((short)8), ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL + }; + + for (int i=0; i<testArgValues.length; i++){ + invokeTest( m, testArgValues[i], expected[i]); + } + } + } + + //--- char argument + char _test(char v){ + //System.out.println("-- test(char) got " + v); + return v; + } + + @Test + public void argTestChar() throws NoSuchMethodException { + if (verifyNoPropertyViolation()){ + Method m = MethodTest.class.getDeclaredMethod("_test", char.class); + Object[] expected = { // all but char throws + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, Character.valueOf('w'), ILLEGAL, ILLEGAL + }; + + for (int i=0; i<testArgValues.length; i++){ + invokeTest( m, testArgValues[i], expected[i]); + } + } + } + + + //--- int argument + int _test(int v){ + //System.out.println("-- test(int) got " + v); + return v; + } + + @Test + public void argTestInt() throws NoSuchMethodException { + if (verifyNoPropertyViolation()){ + Method m = MethodTest.class.getDeclaredMethod("_test", int.class); + Object[] expected = { // all but byte, short, int and char throws + Integer.valueOf(7), Integer.valueOf(8), Integer.valueOf(9), ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, + Integer.valueOf('w'), ILLEGAL, ILLEGAL + }; + + for (int i=0; i<testArgValues.length; i++){ + invokeTest( m, testArgValues[i], expected[i]); + } + } + } + + + //--- long argument + long _test(long v){ + //System.out.println("-- test(long) got " + v); + return v; + } + + @Test + public void argTestLong() throws NoSuchMethodException { + if (verifyNoPropertyViolation()){ + Method m = MethodTest.class.getDeclaredMethod("_test", long.class); + Object[] expected = { + Long.valueOf(7L),Long.valueOf(8L), Long.valueOf(9L), Long.valueOf(10L), + ILLEGAL, ILLEGAL, ILLEGAL, Long.valueOf('w'), ILLEGAL, ILLEGAL + }; + + for (int i=0; i<testArgValues.length; i++){ + invokeTest( m, testArgValues[i], expected[i]); + } + } + } + + //--- float argument + float _test(float v){ + //System.out.println("-- test(float) got " + v); + return v; + } + + @Test + public void argTestFloat() throws NoSuchMethodException { + if (verifyNoPropertyViolation()){ + Method m = MethodTest.class.getDeclaredMethod("_test", float.class); + Object[] expected = { + Float.valueOf(7f), Float.valueOf(8f), Float.valueOf(9f), + Float.valueOf(10f), Float.valueOf(3.1415f), ILLEGAL, ILLEGAL, + Float.valueOf('w'), ILLEGAL, ILLEGAL + }; + + for (int i=0; i<testArgValues.length; i++){ + invokeTest( m, testArgValues[i], expected[i]); + } + } + } + + //--- double argument + double _test(double v){ + //System.out.println("-- test(double) got " + v); + return v; + } + + @Test + public void argTestDouble() throws NoSuchMethodException { + if (verifyNoPropertyViolation()){ + Method m = MethodTest.class.getDeclaredMethod("_test", double.class); + Object[] expected = { + Double.valueOf(7.0), Double.valueOf(8.0), Double.valueOf(9.0), + Double.valueOf(10.0), Double.valueOf(3.1415f), Double.valueOf(3.14159), + ILLEGAL, Double.valueOf('w'), ILLEGAL, ILLEGAL + }; + + for (int i=0; i<testArgValues.length; i++){ + invokeTest( m, testArgValues[i], expected[i]); + } + } + } + + //--- String argument + String _test(String v){ + //System.out.println("-- test(String) got " + v); + return v; + } + + @Test + public void argTestString() throws NoSuchMethodException { + if (verifyNoPropertyViolation()){ + Method m = MethodTest.class.getDeclaredMethod("_test", String.class); + Object[] expected = { + ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, ILLEGAL, "hello", null + }; + + for (int i=0; i<testArgValues.length; i++){ + invokeTest( m, testArgValues[i], expected[i]); + } + } + } + + //--- Object argument + Object _test(Object v){ + //System.out.println("-- test(String) got " + v); + return v; + } + + @Test + public void argTestObject() throws NoSuchMethodException { + if (verifyNoPropertyViolation()){ + Method m = MethodTest.class.getDeclaredMethod("_test", Object.class); + Object[] expected = testArgValues; + + for (int i=0; i<testArgValues.length; i++){ + invokeTest( m, testArgValues[i], expected[i]); + } + } + } + + //--- Number argument + Number _test(Number v){ + //System.out.println("-- test(Number) got " + v); + return v; + } + + @Test + public void argTestNumber() throws NoSuchMethodException { + if (verifyNoPropertyViolation()){ + Method m = MethodTest.class.getDeclaredMethod("_test", Number.class); + Object[] expected = { + Byte.valueOf((byte) 7), + Short.valueOf((short) 8), + Integer.valueOf(9), + Long.valueOf(10), + Float.valueOf(3.1415f), + Double.valueOf(3.14159), + ILLEGAL, + ILLEGAL, + ILLEGAL, + null // we already used the real null to flag an IllegalArgumentException + }; + + for (int i=0; i<testArgValues.length; i++){ + invokeTest( m, testArgValues[i], expected[i]); + } + } + } + + //--- array argument + int[] _test(int[] v){ + //System.out.println("-- test(int[]) got " + v); + return v; + } + + @Test + public void argTestIntArray() throws NoSuchMethodException { + if (verifyNoPropertyViolation()){ + Method m = MethodTest.class.getDeclaredMethod("_test", int[].class); + Object[] testVals = { + new int[0], + new float[0], + "blah", + null + }; + Object[] expected = { + testVals[0], + ILLEGAL, + ILLEGAL, + null + }; + + for (int i=0; i<testVals.length; i++){ + invokeTest( m, testVals[i], expected[i]); + } + } + } + + + //--- parameter annotation reflection + + @Retention(RetentionPolicy.RUNTIME) + @interface A { + String value(); + } + + void noFoo() {} + void noFoo(int a) {} + void oneFoo (@A("arg 1")int a){} + void twoFoo (int a, @A("arg 2") int b){} + + @Test + public void testParameterAnnotations(){ + if (verifyNoPropertyViolation()){ + try { + Method mth; + Annotation[][] pai; + Class<MethodTest> cls = MethodTest.class; +/** + mth = cls.getDeclaredMethod("noFoo"); + pai = mth.getParameterAnnotations(); + assertTrue("should return Annotation[0][] for noFoo()", pai != null && pai.length == 0); + + mth = cls.getDeclaredMethod("noFoo", int.class ); + pai = mth.getParameterAnnotations(); + assertTrue("should return Annotation[1][{}] for noFoo(int)", pai != null && pai.length == 1 + && ((pai[0] != null) && (pai[0].length == 0))); + System.out.println("noFoo(int) : " + pai[0]); +**/ + mth = cls.getDeclaredMethod("oneFoo", int.class); + pai = mth.getParameterAnnotations(); + assertTrue("should return Annotation[1][{@A}] for oneFoo(int)", pai != null && pai.length == 1 + && ((pai[0] != null) && (pai[0].length == 1) && (pai[0][0] instanceof A))); + System.out.println("oneFoo(@A int) : " + pai[0][0]); + + mth = cls.getDeclaredMethod("twoFoo", int.class, int.class); + pai = mth.getParameterAnnotations(); + assertTrue("should return Annotation[1][{@A}{}] for twoFoo(int,int)", pai != null && pai.length == 2 + && ((pai[0] != null) && (pai[0].length == 0)) + && ((pai[1] != null) && (pai[1].length == 1) && (pai[1][0] instanceof A))); + System.out.println("twoFoo(int, @A int) : " + pai[0] + ',' + pai[1][0]); + + + } catch (Throwable t){ + t.printStackTrace(); + fail("retrieving parameter annotation failed: " + t); + } + + } + } + +}