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       // Check for moving GC bugs in proxy stubs.
     61       Runtime.getRuntime().gc();
     62       if (name.endsWith("Foo")) {
     63         check(args == null);
     64         fooInvocations++;
     65       } else if (name.endsWith("Bar")) {
     66         check(args == null);
     67         barInvocations++;
     68       }
     69       if (causeNpeOnReturn) {
     70         return null;
     71       } else if (name.equals("voidFoo") || name.equals("voidBar")) {
     72         return null;
     73       } else if (name.equals("booleanFoo")) {
     74         return true;
     75       } else if (name.equals("booleanBar")) {
     76         return false;
     77       } else if (name.equals("selectArg")) {
     78         check(args.length == 6);
     79         int select = (Integer)args[0];
     80         return args[select];
     81       } else {
     82         try {
     83           if (name.endsWith("Foo")) {
     84             return returnType.getField("MAX_VALUE").get(null);
     85           } else {
     86             check(name.endsWith("Bar"));
     87             return returnType.getField("MIN_VALUE").get(null);
     88           }
     89         } catch (Exception e) {
     90           throw new Error("return type = " + returnType, e);
     91         }
     92       }
     93     }
     94   }
     95 
     96   static void testProxyReturns() {
     97     System.out.println(testName + ".testProxyReturns RUNNING");
     98     MyInvocationHandler myHandler = new MyInvocationHandler();
     99     MyInterface proxyMyInterface =
    100         (MyInterface)Proxy.newProxyInstance(ReturnsAndArgPassing.class.getClassLoader(),
    101                                             new Class<?>[] { MyInterface.class },
    102                                             myHandler);
    103     check(fooInvocations == 0);
    104     proxyMyInterface.voidFoo();
    105     check(fooInvocations == 1);
    106 
    107     check(barInvocations == 0);
    108     proxyMyInterface.voidBar();
    109     check(barInvocations == 1);
    110 
    111     check(fooInvocations == 1);
    112     myHandler.returnType = Boolean.class;
    113     check(proxyMyInterface.booleanFoo() == true);
    114     check(fooInvocations == 2);
    115 
    116     check(barInvocations == 1);
    117     check(proxyMyInterface.booleanBar() == false);
    118     check(barInvocations == 2);
    119 
    120     check(fooInvocations == 2);
    121     myHandler.returnType = Byte.class;
    122     check(proxyMyInterface.byteFoo() == Byte.MAX_VALUE);
    123     check(fooInvocations == 3);
    124 
    125     check(barInvocations == 2);
    126     check(proxyMyInterface.byteBar() == Byte.MIN_VALUE);
    127     check(barInvocations == 3);
    128 
    129     check(fooInvocations == 3);
    130     myHandler.returnType = Character.class;
    131     check(proxyMyInterface.charFoo() == Character.MAX_VALUE);
    132     check(fooInvocations == 4);
    133 
    134     check(barInvocations == 3);
    135     check(proxyMyInterface.charBar() == Character.MIN_VALUE);
    136     check(barInvocations == 4);
    137 
    138     check(fooInvocations == 4);
    139     myHandler.returnType = Short.class;
    140     check(proxyMyInterface.shortFoo() == Short.MAX_VALUE);
    141     check(fooInvocations == 5);
    142 
    143     check(barInvocations == 4);
    144     check(proxyMyInterface.shortBar() == Short.MIN_VALUE);
    145     check(barInvocations == 5);
    146 
    147     check(fooInvocations == 5);
    148     myHandler.returnType = Integer.class;
    149     check(proxyMyInterface.intFoo() == Integer.MAX_VALUE);
    150     check(fooInvocations == 6);
    151 
    152     check(barInvocations == 5);
    153     check(proxyMyInterface.intBar() == Integer.MIN_VALUE);
    154     check(barInvocations == 6);
    155 
    156     check(fooInvocations == 6);
    157     myHandler.returnType = Long.class;
    158     check(proxyMyInterface.longFoo() == Long.MAX_VALUE);
    159     check(fooInvocations == 7);
    160 
    161     check(barInvocations == 6);
    162     check(proxyMyInterface.longBar() == Long.MIN_VALUE);
    163     check(barInvocations == 7);
    164 
    165     check(fooInvocations == 7);
    166     myHandler.returnType = Float.class;
    167     check(proxyMyInterface.floatFoo() == Float.MAX_VALUE);
    168     check(fooInvocations == 8);
    169 
    170     check(barInvocations == 7);
    171     check(proxyMyInterface.floatBar() == Float.MIN_VALUE);
    172     check(barInvocations == 8);
    173 
    174     check(fooInvocations == 8);
    175     myHandler.returnType = Double.class;
    176     check(proxyMyInterface.doubleFoo() == Double.MAX_VALUE);
    177     check(fooInvocations == 9);
    178 
    179     check(barInvocations == 8);
    180     check(proxyMyInterface.doubleBar() == Double.MIN_VALUE);
    181     check(barInvocations == 9);
    182 
    183     // Toggle flag to get return values to cause NPEs
    184     myHandler.causeNpeOnReturn = true;
    185 
    186     check(fooInvocations == 9);
    187     try {
    188         proxyMyInterface.booleanFoo();
    189         throw new AssertionError("Expected NPE");
    190     } catch (NullPointerException e) {
    191     }
    192     check(fooInvocations == 10);
    193 
    194     check(barInvocations == 9);
    195     try {
    196         proxyMyInterface.booleanBar();
    197         throw new AssertionError("Expected NPE");
    198     } catch (NullPointerException e) {
    199     }
    200     check(barInvocations == 10);
    201 
    202     check(fooInvocations == 10);
    203     try {
    204         proxyMyInterface.byteFoo();
    205         throw new AssertionError("Expected NPE");
    206     } catch (NullPointerException e) {
    207     }
    208     check(fooInvocations == 11);
    209 
    210     check(barInvocations == 10);
    211     try {
    212         proxyMyInterface.byteBar();
    213         throw new AssertionError("Expected NPE");
    214     } catch (NullPointerException e) {
    215     }
    216     check(barInvocations == 11);
    217 
    218     check(fooInvocations == 11);
    219     try {
    220         proxyMyInterface.charFoo();
    221         throw new AssertionError("Expected NPE");
    222     } catch (NullPointerException e) {
    223     }
    224     check(fooInvocations == 12);
    225 
    226     check(barInvocations == 11);
    227     try {
    228         proxyMyInterface.charBar();
    229         throw new AssertionError("Expected NPE");
    230     } catch (NullPointerException e) {
    231     }
    232     check(barInvocations == 12);
    233 
    234     check(fooInvocations == 12);
    235     try {
    236         proxyMyInterface.shortFoo();
    237         throw new AssertionError("Expected NPE");
    238     } catch (NullPointerException e) {
    239     }
    240     check(fooInvocations == 13);
    241 
    242     check(barInvocations == 12);
    243     try {
    244         proxyMyInterface.shortBar();
    245         throw new AssertionError("Expected NPE");
    246     } catch (NullPointerException e) {
    247     }
    248     check(barInvocations == 13);
    249 
    250     check(fooInvocations == 13);
    251     try {
    252         proxyMyInterface.intFoo();
    253         throw new AssertionError("Expected NPE");
    254     } catch (NullPointerException e) {
    255     }
    256     check(fooInvocations == 14);
    257 
    258     check(barInvocations == 13);
    259     try {
    260         proxyMyInterface.intBar();
    261         throw new AssertionError("Expected NPE");
    262     } catch (NullPointerException e) {
    263     }
    264     check(barInvocations == 14);
    265 
    266     check(fooInvocations == 14);
    267     try {
    268         proxyMyInterface.longFoo();
    269         throw new AssertionError("Expected NPE");
    270     } catch (NullPointerException e) {
    271     }
    272     check(fooInvocations == 15);
    273 
    274     check(barInvocations == 14);
    275     try {
    276         proxyMyInterface.longBar();
    277         throw new AssertionError("Expected NPE");
    278     } catch (NullPointerException e) {
    279     }
    280     check(barInvocations == 15);
    281 
    282     check(fooInvocations == 15);
    283     try {
    284         proxyMyInterface.floatFoo();
    285         throw new AssertionError("Expected NPE");
    286     } catch (NullPointerException e) {
    287     }
    288     check(fooInvocations == 16);
    289 
    290     check(barInvocations == 15);
    291     try {
    292         proxyMyInterface.floatBar();
    293         throw new AssertionError("Expected NPE");
    294     } catch (NullPointerException e) {
    295     }
    296     check(barInvocations == 16);
    297 
    298     check(fooInvocations == 16);
    299     try {
    300         proxyMyInterface.doubleFoo();
    301         throw new AssertionError("Expected NPE");
    302     } catch (NullPointerException e) {
    303     }
    304     check(fooInvocations == 17);
    305 
    306     check(barInvocations == 16);
    307     try {
    308         proxyMyInterface.doubleBar();
    309         throw new AssertionError("Expected NPE");
    310     } catch (NullPointerException e) {
    311     }
    312     check(barInvocations == 17);
    313 
    314     // Toggle flag to stop NPEs
    315     myHandler.causeNpeOnReturn = false;
    316 
    317     check(fooInvocations == 17);
    318     myHandler.returnType = Double.class;  // Double -> byte == fail
    319     try {
    320         proxyMyInterface.byteFoo();
    321         throw new AssertionError("Expected ClassCastException");
    322     } catch (ClassCastException e) {
    323     }
    324     check(fooInvocations == 18);
    325 
    326     check(barInvocations == 17);
    327     try {
    328         proxyMyInterface.byteBar();
    329         throw new AssertionError("Expected NPE");
    330     } catch (ClassCastException e) {
    331     }
    332     check(barInvocations == 18);
    333 
    334     check(fooInvocations == 18);
    335     myHandler.returnType = Float.class;  // Float -> byte == fail
    336     try {
    337         proxyMyInterface.byteFoo();
    338         throw new AssertionError("Expected ClassCastException");
    339     } catch (ClassCastException e) {
    340     }
    341     check(fooInvocations == 19);
    342 
    343     check(barInvocations == 18);
    344     try {
    345         proxyMyInterface.byteBar();
    346         throw new AssertionError("Expected NPE");
    347     } catch (ClassCastException e) {
    348     }
    349     check(barInvocations == 19);
    350 
    351     check(fooInvocations == 19);
    352     myHandler.returnType = Long.class;  // Long -> byte == fail
    353     try {
    354         proxyMyInterface.byteFoo();
    355         throw new AssertionError("Expected ClassCastException");
    356     } catch (ClassCastException e) {
    357     }
    358     check(fooInvocations == 20);
    359 
    360     check(barInvocations == 19);
    361     try {
    362         proxyMyInterface.byteBar();
    363         throw new AssertionError("Expected NPE");
    364     } catch (ClassCastException e) {
    365     }
    366     check(barInvocations == 20);
    367 
    368     check(fooInvocations == 20);
    369     myHandler.returnType = Integer.class;  // Int -> byte == fail
    370     try {
    371         proxyMyInterface.byteFoo();
    372         throw new AssertionError("Expected ClassCastException");
    373     } catch (ClassCastException e) {
    374     }
    375     check(fooInvocations == 21);
    376 
    377     check(barInvocations == 20);
    378     try {
    379         proxyMyInterface.byteBar();
    380         throw new AssertionError("Expected NPE");
    381     } catch (ClassCastException e) {
    382     }
    383     check(barInvocations == 21);
    384 
    385     check(fooInvocations == 21);
    386     myHandler.returnType = Short.class;  // Short -> byte == fail
    387     try {
    388         proxyMyInterface.byteFoo();
    389         throw new AssertionError("Expected ClassCastException");
    390     } catch (ClassCastException e) {
    391     }
    392     check(fooInvocations == 22);
    393 
    394     check(barInvocations == 21);
    395     try {
    396         proxyMyInterface.byteBar();
    397         throw new AssertionError("Expected NPE");
    398     } catch (ClassCastException e) {
    399     }
    400     check(barInvocations == 22);
    401 
    402     check(fooInvocations == 22);
    403     myHandler.returnType = Character.class;  // Char -> byte == fail
    404     try {
    405         proxyMyInterface.byteFoo();
    406         throw new AssertionError("Expected ClassCastException");
    407     } catch (ClassCastException e) {
    408     }
    409     check(fooInvocations == 23);
    410 
    411     check(barInvocations == 22);
    412     try {
    413         proxyMyInterface.byteBar();
    414         throw new AssertionError("Expected NPE");
    415     } catch (ClassCastException e) {
    416     }
    417     check(barInvocations == 23);
    418 
    419     check(fooInvocations == 23);
    420     myHandler.returnType = Character.class;  // Char -> short == fail
    421     try {
    422         proxyMyInterface.shortFoo();
    423         throw new AssertionError("Expected ClassCastException");
    424     } catch (ClassCastException e) {
    425     }
    426     check(fooInvocations == 24);
    427 
    428     check(barInvocations == 23);
    429     try {
    430         proxyMyInterface.shortBar();
    431         throw new AssertionError("Expected NPE");
    432     } catch (ClassCastException e) {
    433     }
    434     check(barInvocations == 24);
    435 
    436     System.out.println(testName + ".testProxyReturns PASSED");
    437   }
    438 
    439   static void testProxyArgPassing() {
    440     System.out.println(testName + ".testProxyArgPassing RUNNING");
    441     MyInvocationHandler myHandler = new MyInvocationHandler();
    442     MyInterface proxyMyInterface =
    443         (MyInterface)Proxy.newProxyInstance(ReturnsAndArgPassing.class.getClassLoader(),
    444                                             new Class<?>[] { MyInterface.class },
    445                                             myHandler);
    446 
    447     check((Integer)proxyMyInterface.selectArg(0, Integer.MAX_VALUE, Long.MAX_VALUE,
    448         Float.MAX_VALUE, Double.MAX_VALUE, Object.class) == 0);
    449     check((Integer)proxyMyInterface.selectArg(1, Integer.MAX_VALUE, Long.MAX_VALUE,
    450         Float.MAX_VALUE, Double.MAX_VALUE, Object.class) == Integer.MAX_VALUE);
    451     check((Long)proxyMyInterface.selectArg(2, Integer.MAX_VALUE, Long.MAX_VALUE,
    452         Float.MAX_VALUE, Double.MAX_VALUE, Object.class) == Long.MAX_VALUE);
    453     check((Float)proxyMyInterface.selectArg(3, Integer.MAX_VALUE, Long.MAX_VALUE,
    454         Float.MAX_VALUE, Double.MAX_VALUE, Object.class) == Float.MAX_VALUE);
    455     check((Double)proxyMyInterface.selectArg(4, Integer.MAX_VALUE, Long.MAX_VALUE,
    456         Float.MAX_VALUE, Double.MAX_VALUE, Object.class) == Double.MAX_VALUE);
    457     check(proxyMyInterface.selectArg(5, Integer.MAX_VALUE, Long.MAX_VALUE,
    458         Float.MAX_VALUE, Double.MAX_VALUE, Object.class) == Object.class);
    459 
    460     System.out.println(testName + ".testProxyArgPassing PASSED");
    461   }
    462 
    463   public static void main(String args[]) {
    464     testProxyReturns();
    465     testProxyArgPassing();
    466   }
    467 }
    468