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);
+      }
+
+    }
+  }
+  
+}