Home | History | Annotate | Download | only in src
      1 /*
      2  * Copyright (C) 2011 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 import java.lang.reflect.*;
     17 
     18 public class ReturnsAndArgPassing {
     19 
     20   public static final String testName = "ReturnsAndArgPassing";
     21 
     22   static void check(boolean x) {
     23     if (!x) {
     24       throw new AssertionError(testName + " Check failed");
     25     }
     26   }
     27 
     28   interface MyInterface {
     29     void voidFoo();
     30     void voidBar();
     31     boolean booleanFoo();
     32     boolean booleanBar();
     33     byte byteFoo();
     34     byte byteBar();
     35     char charFoo();
     36     char charBar();
     37     short shortFoo();
     38     short shortBar();
     39     int intFoo();
     40     int intBar();
     41     long longFoo();
     42     long longBar();
     43     float floatFoo();
     44     float floatBar();
     45     double doubleFoo();
     46     double doubleBar();
     47     Object selectArg(int select, int a, long b, float c, double d, Object x);
     48   }
     49 
     50   static int fooInvocations = 0;
     51   static int barInvocations = 0;
     52 
     53   static class MyInvocationHandler implements InvocationHandler {
     54     boolean causeNpeOnReturn = false;
     55     Class<?> returnType = null;
     56     public Object invoke(Object proxy, Method method, Object[] args) {
     57       check(proxy instanceof Proxy);
     58       check(method.getDeclaringClass() == MyInterface.class);
     59       String name = method.getName();
     60       if (name.endsWith("Foo")) {
     61         check(args == null);
     62         fooInvocations++;
     63       } else if (name.endsWith("Bar")) {
     64         check(args == null);
     65         barInvocations++;
     66       }
     67       if (causeNpeOnReturn) {
     68         return null;
     69       } else if (name.equals("voidFoo") || name.equals("voidBar")) {
     70         return null;
     71       } else if (name.equals("booleanFoo")) {
     72         return true;
     73       } else if (name.equals("booleanBar")) {
     74         return false;
     75       } else if (name.equals("selectArg")) {
     76         check(args.length == 6);
     77         int select = (Integer)args[0];
     78         return args[select];
     79       } else {
     80         try {
     81           if (name.endsWith("Foo")) {
     82             return returnType.getField("MAX_VALUE").get(null);
     83           } else {
     84             check(name.endsWith("Bar"));
     85             return returnType.getField("MIN_VALUE").get(null);
     86           }
     87         } catch (Exception e) {
     88           throw new Error("return type = " + returnType, e);
     89         }
     90       }
     91     }
     92   }
     93 
     94   static void testProxyReturns() {
     95     System.out.println(testName + ".testProxyReturns RUNNING");
     96     MyInvocationHandler myHandler = new MyInvocationHandler();
     97     MyInterface proxyMyInterface =
     98         (MyInterface)Proxy.newProxyInstance(ReturnsAndArgPassing.class.getClassLoader(),
     99                                             new Class[] { MyInterface.class },
    100                                             myHandler);
    101     check(fooInvocations == 0);
    102     proxyMyInterface.voidFoo();
    103     check(fooInvocations == 1);
    104 
    105     check(barInvocations == 0);
    106     proxyMyInterface.voidBar();
    107     check(barInvocations == 1);
    108 
    109     check(fooInvocations == 1);
    110     myHandler.returnType = Boolean.class;
    111     check(proxyMyInterface.booleanFoo() == true);
    112     check(fooInvocations == 2);
    113 
    114     check(barInvocations == 1);
    115     check(proxyMyInterface.booleanBar() == false);
    116     check(barInvocations == 2);
    117 
    118     check(fooInvocations == 2);
    119     myHandler.returnType = Byte.class;
    120     check(proxyMyInterface.byteFoo() == Byte.MAX_VALUE);
    121     check(fooInvocations == 3);
    122 
    123     check(barInvocations == 2);
    124     check(proxyMyInterface.byteBar() == Byte.MIN_VALUE);
    125     check(barInvocations == 3);
    126 
    127     check(fooInvocations == 3);
    128     myHandler.returnType = Character.class;
    129     check(proxyMyInterface.charFoo() == Character.MAX_VALUE);
    130     check(fooInvocations == 4);
    131 
    132     check(barInvocations == 3);
    133     check(proxyMyInterface.charBar() == Character.MIN_VALUE);
    134     check(barInvocations == 4);
    135 
    136     check(fooInvocations == 4);
    137     myHandler.returnType = Short.class;
    138     check(proxyMyInterface.shortFoo() == Short.MAX_VALUE);
    139     check(fooInvocations == 5);
    140 
    141     check(barInvocations == 4);
    142     check(proxyMyInterface.shortBar() == Short.MIN_VALUE);
    143     check(barInvocations == 5);
    144 
    145     check(fooInvocations == 5);
    146     myHandler.returnType = Integer.class;
    147     check(proxyMyInterface.intFoo() == Integer.MAX_VALUE);
    148     check(fooInvocations == 6);
    149 
    150     check(barInvocations == 5);
    151     check(proxyMyInterface.intBar() == Integer.MIN_VALUE);
    152     check(barInvocations == 6);
    153 
    154     check(fooInvocations == 6);
    155     myHandler.returnType = Long.class;
    156     check(proxyMyInterface.longFoo() == Long.MAX_VALUE);
    157     check(fooInvocations == 7);
    158 
    159     check(barInvocations == 6);
    160     check(proxyMyInterface.longBar() == Long.MIN_VALUE);
    161     check(barInvocations == 7);
    162 
    163     check(fooInvocations == 7);
    164     myHandler.returnType = Float.class;
    165     check(proxyMyInterface.floatFoo() == Float.MAX_VALUE);
    166     check(fooInvocations == 8);
    167 
    168     check(barInvocations == 7);
    169     check(proxyMyInterface.floatBar() == Float.MIN_VALUE);
    170     check(barInvocations == 8);
    171 
    172     check(fooInvocations == 8);
    173     myHandler.returnType = Double.class;
    174     check(proxyMyInterface.doubleFoo() == Double.MAX_VALUE);
    175     check(fooInvocations == 9);
    176 
    177     check(barInvocations == 8);
    178     check(proxyMyInterface.doubleBar() == Double.MIN_VALUE);
    179     check(barInvocations == 9);
    180 
    181     // Toggle flag to get return values to cause NPEs
    182     myHandler.causeNpeOnReturn = true;
    183 
    184     check(fooInvocations == 9);
    185     try {
    186         proxyMyInterface.booleanFoo();
    187         throw new AssertionError("Expected NPE");
    188     } catch (NullPointerException e) {
    189     }
    190     check(fooInvocations == 10);
    191 
    192     check(barInvocations == 9);
    193     try {
    194         proxyMyInterface.booleanBar();
    195         throw new AssertionError("Expected NPE");
    196     } catch (NullPointerException e) {
    197     }
    198     check(barInvocations == 10);
    199 
    200     check(fooInvocations == 10);
    201     try {
    202         proxyMyInterface.byteFoo();
    203         throw new AssertionError("Expected NPE");
    204     } catch (NullPointerException e) {
    205     }
    206     check(fooInvocations == 11);
    207 
    208     check(barInvocations == 10);
    209     try {
    210         proxyMyInterface.byteBar();
    211         throw new AssertionError("Expected NPE");
    212     } catch (NullPointerException e) {
    213     }
    214     check(barInvocations == 11);
    215 
    216     check(fooInvocations == 11);
    217     try {
    218         proxyMyInterface.charFoo();
    219         throw new AssertionError("Expected NPE");
    220     } catch (NullPointerException e) {
    221     }
    222     check(fooInvocations == 12);
    223 
    224     check(barInvocations == 11);
    225     try {
    226         proxyMyInterface.charBar();
    227         throw new AssertionError("Expected NPE");
    228     } catch (NullPointerException e) {
    229     }
    230     check(barInvocations == 12);
    231 
    232     check(fooInvocations == 12);
    233     try {
    234         proxyMyInterface.shortFoo();
    235         throw new AssertionError("Expected NPE");
    236     } catch (NullPointerException e) {
    237     }
    238     check(fooInvocations == 13);
    239 
    240     check(barInvocations == 12);
    241     try {
    242         proxyMyInterface.shortBar();
    243         throw new AssertionError("Expected NPE");
    244     } catch (NullPointerException e) {
    245     }
    246     check(barInvocations == 13);
    247 
    248     check(fooInvocations == 13);
    249     try {
    250         proxyMyInterface.intFoo();
    251         throw new AssertionError("Expected NPE");
    252     } catch (NullPointerException e) {
    253     }
    254     check(fooInvocations == 14);
    255 
    256     check(barInvocations == 13);
    257     try {
    258         proxyMyInterface.intBar();
    259         throw new AssertionError("Expected NPE");
    260     } catch (NullPointerException e) {
    261     }
    262     check(barInvocations == 14);
    263 
    264     check(fooInvocations == 14);
    265     try {
    266         proxyMyInterface.longFoo();
    267         throw new AssertionError("Expected NPE");
    268     } catch (NullPointerException e) {
    269     }
    270     check(fooInvocations == 15);
    271 
    272     check(barInvocations == 14);
    273     try {
    274         proxyMyInterface.longBar();
    275         throw new AssertionError("Expected NPE");
    276     } catch (NullPointerException e) {
    277     }
    278     check(barInvocations == 15);
    279 
    280     check(fooInvocations == 15);
    281     try {
    282         proxyMyInterface.floatFoo();
    283         throw new AssertionError("Expected NPE");
    284     } catch (NullPointerException e) {
    285     }
    286     check(fooInvocations == 16);
    287 
    288     check(barInvocations == 15);
    289     try {
    290         proxyMyInterface.floatBar();
    291         throw new AssertionError("Expected NPE");
    292     } catch (NullPointerException e) {
    293     }
    294     check(barInvocations == 16);
    295 
    296     check(fooInvocations == 16);
    297     try {
    298         proxyMyInterface.doubleFoo();
    299         throw new AssertionError("Expected NPE");
    300     } catch (NullPointerException e) {
    301     }
    302     check(fooInvocations == 17);
    303 
    304     check(barInvocations == 16);
    305     try {
    306         proxyMyInterface.doubleBar();
    307         throw new AssertionError("Expected NPE");
    308     } catch (NullPointerException e) {
    309     }
    310     check(barInvocations == 17);
    311 
    312     // Toggle flag to stop NPEs
    313     myHandler.causeNpeOnReturn = false;
    314 
    315     check(fooInvocations == 17);
    316     myHandler.returnType = Double.class;  // Double -> byte == fail
    317     try {
    318         proxyMyInterface.byteFoo();
    319         throw new AssertionError("Expected ClassCastException");
    320     } catch (ClassCastException e) {
    321     }
    322     check(fooInvocations == 18);
    323 
    324     check(barInvocations == 17);
    325     try {
    326         proxyMyInterface.byteBar();
    327         throw new AssertionError("Expected NPE");
    328     } catch (ClassCastException e) {
    329     }
    330     check(barInvocations == 18);
    331 
    332     check(fooInvocations == 18);
    333     myHandler.returnType = Float.class;  // Float -> byte == fail
    334     try {
    335         proxyMyInterface.byteFoo();
    336         throw new AssertionError("Expected ClassCastException");
    337     } catch (ClassCastException e) {
    338     }
    339     check(fooInvocations == 19);
    340 
    341     check(barInvocations == 18);
    342     try {
    343         proxyMyInterface.byteBar();
    344         throw new AssertionError("Expected NPE");
    345     } catch (ClassCastException e) {
    346     }
    347     check(barInvocations == 19);
    348 
    349     check(fooInvocations == 19);
    350     myHandler.returnType = Long.class;  // Long -> byte == fail
    351     try {
    352         proxyMyInterface.byteFoo();
    353         throw new AssertionError("Expected ClassCastException");
    354     } catch (ClassCastException e) {
    355     }
    356     check(fooInvocations == 20);
    357 
    358     check(barInvocations == 19);
    359     try {
    360         proxyMyInterface.byteBar();
    361         throw new AssertionError("Expected NPE");
    362     } catch (ClassCastException e) {
    363     }
    364     check(barInvocations == 20);
    365 
    366     check(fooInvocations == 20);
    367     myHandler.returnType = Integer.class;  // Int -> byte == fail
    368     try {
    369         proxyMyInterface.byteFoo();
    370         throw new AssertionError("Expected ClassCastException");
    371     } catch (ClassCastException e) {
    372     }
    373     check(fooInvocations == 21);
    374 
    375     check(barInvocations == 20);
    376     try {
    377         proxyMyInterface.byteBar();
    378         throw new AssertionError("Expected NPE");
    379     } catch (ClassCastException e) {
    380     }
    381     check(barInvocations == 21);
    382 
    383     check(fooInvocations == 21);
    384     myHandler.returnType = Short.class;  // Short -> byte == fail
    385     try {
    386         proxyMyInterface.byteFoo();
    387         throw new AssertionError("Expected ClassCastException");
    388     } catch (ClassCastException e) {
    389     }
    390     check(fooInvocations == 22);
    391 
    392     check(barInvocations == 21);
    393     try {
    394         proxyMyInterface.byteBar();
    395         throw new AssertionError("Expected NPE");
    396     } catch (ClassCastException e) {
    397     }
    398     check(barInvocations == 22);
    399 
    400     check(fooInvocations == 22);
    401     myHandler.returnType = Character.class;  // Char -> byte == fail
    402     try {
    403         proxyMyInterface.byteFoo();
    404         throw new AssertionError("Expected ClassCastException");
    405     } catch (ClassCastException e) {
    406     }
    407     check(fooInvocations == 23);
    408 
    409     check(barInvocations == 22);
    410     try {
    411         proxyMyInterface.byteBar();
    412         throw new AssertionError("Expected NPE");
    413     } catch (ClassCastException e) {
    414     }
    415     check(barInvocations == 23);
    416 
    417     check(fooInvocations == 23);
    418     myHandler.returnType = Character.class;  // Char -> short == fail
    419     try {
    420         proxyMyInterface.shortFoo();
    421         throw new AssertionError("Expected ClassCastException");
    422     } catch (ClassCastException e) {
    423     }
    424     check(fooInvocations == 24);
    425 
    426     check(barInvocations == 23);
    427     try {
    428         proxyMyInterface.shortBar();
    429         throw new AssertionError("Expected NPE");
    430     } catch (ClassCastException e) {
    431     }
    432     check(barInvocations == 24);
    433 
    434     System.out.println(testName + ".testProxyReturns PASSED");
    435   }
    436 
    437   static void testProxyArgPassing() {
    438     System.out.println(testName + ".testProxyArgPassing RUNNING");
    439     MyInvocationHandler myHandler = new MyInvocationHandler();
    440     MyInterface proxyMyInterface =
    441         (MyInterface)Proxy.newProxyInstance(ReturnsAndArgPassing.class.getClassLoader(),
    442                                             new Class[] { MyInterface.class },
    443                                             myHandler);
    444 
    445     check((Integer)proxyMyInterface.selectArg(0, Integer.MAX_VALUE, Long.MAX_VALUE,
    446         Float.MAX_VALUE, Double.MAX_VALUE, Object.class) == 0);
    447     check((Integer)proxyMyInterface.selectArg(1, Integer.MAX_VALUE, Long.MAX_VALUE,
    448         Float.MAX_VALUE, Double.MAX_VALUE, Object.class) == Integer.MAX_VALUE);
    449     check((Long)proxyMyInterface.selectArg(2, Integer.MAX_VALUE, Long.MAX_VALUE,
    450         Float.MAX_VALUE, Double.MAX_VALUE, Object.class) == Long.MAX_VALUE);
    451     check((Float)proxyMyInterface.selectArg(3, Integer.MAX_VALUE, Long.MAX_VALUE,
    452         Float.MAX_VALUE, Double.MAX_VALUE, Object.class) == Float.MAX_VALUE);
    453     check((Double)proxyMyInterface.selectArg(4, Integer.MAX_VALUE, Long.MAX_VALUE,
    454         Float.MAX_VALUE, Double.MAX_VALUE, Object.class) == Double.MAX_VALUE);
    455     check(proxyMyInterface.selectArg(5, Integer.MAX_VALUE, Long.MAX_VALUE,
    456         Float.MAX_VALUE, Double.MAX_VALUE, Object.class) == Object.class);
    457 
    458     System.out.println(testName + ".testProxyArgPassing PASSED");
    459   }
    460 
    461   public static void main(String args[]) {
    462     testProxyReturns();
    463     testProxyArgPassing();
    464   }
    465 }
    466