1 /*
   2  * Copyright (c) 2016, 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 
  24 package runtime.valhalla.nestmates;
  25 
  26 import org.testng.Assert;
  27 import org.testng.annotations.BeforeClass;
  28 import org.testng.annotations.Test;
  29 import runtime.valhalla.nestmates.p2.MethodHandleSubTop;
  30 
  31 /*
  32  * @test MethodHandleInheritTest
  33  * @summary Verify parent's protected and private methods access from children classes using MethodHandles
  34  * @library /
  35  * @modules java.base
  36  * @compile -XDdisableAccessors p2/MethodHandleSubTop.java
  37  * @run testng runtime.valhalla.nestmates.MethodHandleInheritTest
  38  */
  39 public class MethodHandleInheritTest {
  40 
  41     private static final String METHOD_NAME_PROTECTED = "getField";
  42     private static final String FIELD_NAME_PROTECTED = "field";
  43     private static final String METHOD_NAME_PRIVATE = "privateGetField";
  44     private static final String FIELD_NAME_PRIVATE = "privateField";
  45 
  46     private MethodHandleSubTop methodHandleSubTop;
  47     private MethodHandleSubTop.Inner inner;
  48     private MethodHandleSubTop.Inner.InnerInner innerInner;
  49 
  50     @BeforeClass
  51     public void setUp() {
  52         methodHandleSubTop = new MethodHandleSubTop();
  53         inner = methodHandleSubTop.new Inner();
  54         innerInner = inner.new InnerInner();
  55     }
  56 
  57     /**
  58      * negative case, to verify that there is no access to private method of the parent class from its child
  59      */
  60     @Test(expectedExceptions = {IllegalAccessException.class})
  61     public void testPrivateMethodNeg() throws NoSuchMethodException, IllegalAccessException {
  62         methodHandleSubTop.getSuperMethodMH(METHOD_NAME_PRIVATE);
  63     }
  64 
  65     /**
  66      * negative case, to verify that there is no access to private field of the parent class from its child
  67      */
  68     @Test(expectedExceptions = {IllegalAccessException.class})
  69     public void testPrivateFieldNeg() throws NoSuchFieldException, IllegalAccessException {
  70         methodHandleSubTop.getSuperFieldMH(FIELD_NAME_PRIVATE);
  71     }
  72 
  73     /**
  74      * positive case, to verify that there is access to protected method of the parent class from its child's inner class
  75      */
  76     @Test
  77     public void testProtectedMethodFromInnerPos() throws Throwable {
  78         Assert.assertEquals((int) inner.getSuperMethodMH(METHOD_NAME_PROTECTED).invokeExact(methodHandleSubTop), 1, "inner -> top -> parent method");
  79     }
  80 
  81     /**
  82      * positive case, to verify that there is access to protected field of the parent class from its child's inner class
  83      */
  84     @Test
  85     public void testProtectedFieldFromInnerPos() throws Throwable {
  86         Assert.assertEquals((int) inner.getSuperFieldMH(FIELD_NAME_PROTECTED).invokeExact(methodHandleSubTop), 1, "inner -> top -> parent field");
  87     }
  88 
  89     /**
  90      * positive case, to verify that there is access to protected method of the parent class from its child's inner inner class
  91      */
  92     @Test
  93     public void testProtectedMethodFromInnerInnerPos() throws Throwable {
  94         Assert.assertEquals((int) innerInner.getSuperMethodMH(METHOD_NAME_PROTECTED).invokeExact(methodHandleSubTop), 1, "innerInner -> inner -> top -> parent method");
  95     }
  96 
  97     /**
  98      * positive case, to verify that there is access to protected field of the parent class from its child's inner inner class
  99      */
 100     @Test
 101     public void testProtectedFieldFromInnerInnerPos() throws Throwable {
 102         Assert.assertEquals((int) innerInner.getSuperFieldMH(FIELD_NAME_PROTECTED).invokeExact(methodHandleSubTop), 1, "innerInner -> inner -> top -> parent field");
 103     }
 104 
 105     /**
 106      * positive case, to verify that there is access to protected field and method of the parent class from its child
 107      */
 108     @Test
 109     public void testProtectedAccessFromTopPos() throws Throwable {
 110         Assert.assertEquals((int) methodHandleSubTop.getSuperMethodMH(METHOD_NAME_PROTECTED).invokeExact(methodHandleSubTop), 1, "top -> parent method");
 111         Assert.assertEquals((int) methodHandleSubTop.getSuperFieldMH(FIELD_NAME_PROTECTED).invokeExact(methodHandleSubTop), 1, "top -> parent field");
 112     }
 113 
 114     /**
 115      * negative case, to verify that there is no method access bridge in top accessing from inner
 116      */
 117     @Test(expectedExceptions = {NoSuchMethodException.class})
 118     public void testProtectedMethodAccessFromInnerNeg() throws Throwable {
 119         inner.getSuperProtectedMethodMH();
 120     }
 121 
 122     /**
 123      * negative case, to verify that there is no field access bridge in top accessing from inner
 124      */
 125     @Test(expectedExceptions = {NoSuchMethodException.class})
 126     public void testProtectedFieldAccessFromInnerNeg() throws Throwable {
 127         inner.getSuperProtectedFieldMH();
 128     }
 129 
 130     /**
 131      * negative case, to verify that there is no method access bridge in top accessing from inner's inner
 132      */
 133     @Test(expectedExceptions = {NoSuchMethodException.class})
 134     public void testProtectedMethodAccessFromInnerInnerNeg() throws Throwable {
 135         innerInner.getSuperProtectedMethodMH();
 136     }
 137 
 138     /**
 139      * negative case, to verify that there is no field access bridge in top accessing from inner's inner
 140      */
 141     @Test(expectedExceptions = {NoSuchMethodException.class})
 142     public void testProtectedFieldAccessFromInnerInnerNeg() throws Throwable {
 143         innerInner.getSuperProtectedFieldMH();
 144     }
 145 }