< prev index next >

test/java/lang/StackWalker/Basic.java

Print this page




  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 /*
  25  * @test
  26  * @bug 8140450 8173898
  27  * @summary Basic test for the StackWalker::walk method
  28  * @run testng Basic
  29  */
  30 
  31 import java.lang.StackWalker.StackFrame;


  32 import java.util.List;
  33 import java.util.Objects;
  34 import java.util.stream.Collectors;
  35 import java.util.stream.Stream;
  36 import static java.lang.StackWalker.Option.*;
  37 
  38 import org.testng.annotations.DataProvider;
  39 import org.testng.annotations.Test;
  40 import static org.testng.Assert.*;
  41 
  42 public class Basic {
  43     private static boolean verbose = false;
  44 
  45     @DataProvider(name = "stackDepths")
  46     public static Object[][] stackDepths() {
  47         return new Object[][] {
  48                 { new int[] { 12 },  new int[] { 4, 8, 12}      },
  49                 { new int[] { 18 },  new int[] { 8, 16, 20}     },
  50                 { new int[] { 32 },  new int[] { 16, 32, 64}    },
  51         };
  52     }
  53 


  57      */
  58     @Test(dataProvider = "stackDepths")
  59     public static void test(int[] depth, int[] estimates) {
  60         Basic test = new Basic(depth[0]);
  61         for (int estimate : estimates) {
  62             test.walk(estimate);
  63         }
  64     }
  65 
  66     @Test
  67     public static void testWalkFromConstructor() throws Exception {
  68         System.out.println("testWalkFromConstructor:");
  69         List<String> found = ((ConstructorNewInstance)ConstructorNewInstance.class.getMethod("create")
  70                              .invoke(null)).collectedFrames();
  71         assertEquals(List.of(ConstructorNewInstance.class.getName()+"::<init>",
  72                              ConstructorNewInstance.class.getName()+"::create",
  73                              Basic.class.getName()+"::testWalkFromConstructor"),
  74                      found);
  75     }
  76 























  77     private final int depth;
  78     Basic(int depth) {
  79         this.depth = depth;
  80     }
  81 
  82     /*
  83      * Setup a stack builder with the expected stack depth
  84      * Walk the stack and count the frames.
  85      */
  86     void walk(int estimate) {
  87         int limit = Math.min(depth, 16);
  88         List<StackFrame> frames = new StackBuilder(depth, limit).build();
  89         System.out.format("depth=%d estimate=%d expected=%d walked=%d%n",
  90                           depth, estimate, limit, frames.size());
  91         assertEquals(limit, frames.size());
  92     }
  93 
  94     static class ConstructorNewInstance {
  95         static final StackWalker walker =
  96             StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE);


 115                 return true;
 116             }
 117             // Filter out all other frames (in particular
 118             // those from the test framework) in order to
 119             // have predictable results.
 120             return false;
 121         }
 122         public String frame(StackFrame f) {
 123             return f.getClassName() + "::" + f.getMethodName();
 124         }
 125         List<String> parse(Stream<StackFrame> s) {
 126             return s.filter(this::accept)
 127                     .map(this::frame)
 128                     .collect(Collectors.toList());
 129         }
 130         public static ConstructorNewInstance create() throws Exception {
 131             return ConstructorNewInstance.class.getConstructor().newInstance();
 132         }
 133     }
 134 
 135     class StackBuilder {
 136         private final int stackDepth;
 137         private final int limit;
 138         private int depth = 0;
 139         private List<StackFrame> result;
 140         StackBuilder(int stackDepth, int limit) {
 141             this.stackDepth = stackDepth; // build method;
 142             this.limit = limit;
 143         }
 144         List<StackFrame> build() {
 145             trace("build");
 146             m1();
 147             return result;
 148         }
 149         void m1() {
 150             trace("m1");
 151             m2();
 152         }
 153         void m2() {
 154             trace("m2");
 155             m3();

 156         }
 157         void m3() {
 158             trace("m3");
 159             m4();

 160         }
 161         void m4() {
 162             trace("m4");
 163             int remaining = stackDepth-depth-1;
 164             if (remaining >= 4) {
 165                 m1();
 166             } else {
 167                 filler(remaining);
 168             }
 169         }
 170         void filler(int i) {
 171             trace("filler");
 172             if (i == 0)
 173                 walk();
 174             else
 175                 filler(--i);
 176         }
 177 
 178         void walk() {
 179             StackWalker walker = StackWalker.getInstance(RETAIN_CLASS_REFERENCE);
 180             result = walker.walk(s -> s.limit(limit).collect(Collectors.toList()));
 181         }
 182         void trace(String methodname) {
 183             ++depth;
 184             if (verbose)
 185                 System.out.format("%2d: %s%n", depth, methodname);
 186         }









 187     }
 188 
 189 }


  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 /*
  25  * @test
  26  * @bug 8140450 8173898
  27  * @summary Basic test for the StackWalker::walk method
  28  * @run testng Basic
  29  */
  30 
  31 import java.lang.StackWalker.StackFrame;
  32 import java.lang.invoke.MethodType;
  33 import java.util.HashMap;
  34 import java.util.List;
  35 import java.util.Map;
  36 import java.util.stream.Collectors;
  37 import java.util.stream.Stream;
  38 import static java.lang.StackWalker.Option.*;
  39 
  40 import org.testng.annotations.DataProvider;
  41 import org.testng.annotations.Test;
  42 import static org.testng.Assert.*;
  43 
  44 public class Basic {
  45     private static boolean verbose = false;
  46 
  47     @DataProvider(name = "stackDepths")
  48     public static Object[][] stackDepths() {
  49         return new Object[][] {
  50                 { new int[] { 12 },  new int[] { 4, 8, 12}      },
  51                 { new int[] { 18 },  new int[] { 8, 16, 20}     },
  52                 { new int[] { 32 },  new int[] { 16, 32, 64}    },
  53         };
  54     }
  55 


  59      */
  60     @Test(dataProvider = "stackDepths")
  61     public static void test(int[] depth, int[] estimates) {
  62         Basic test = new Basic(depth[0]);
  63         for (int estimate : estimates) {
  64             test.walk(estimate);
  65         }
  66     }
  67 
  68     @Test
  69     public static void testWalkFromConstructor() throws Exception {
  70         System.out.println("testWalkFromConstructor:");
  71         List<String> found = ((ConstructorNewInstance)ConstructorNewInstance.class.getMethod("create")
  72                              .invoke(null)).collectedFrames();
  73         assertEquals(List.of(ConstructorNewInstance.class.getName()+"::<init>",
  74                              ConstructorNewInstance.class.getName()+"::create",
  75                              Basic.class.getName()+"::testWalkFromConstructor"),
  76                      found);
  77     }
  78 
  79     @Test
  80     public static void testMethodSignature() throws Exception {
  81         List<StackFrame> frames = new StackBuilder(16, 16).build();
  82         Map<String, MethodType> methodTypes = StackBuilder.methodTypes();
  83         for (StackFrame f : frames) {
  84             MethodType type = methodTypes.get(f.getMethodName());
  85             if (type != null) {
  86                 System.out.format("%s.%s %s%n", f.getClassName(), f.getMethodName(),
  87                                   f.getDescriptor());
  88 
  89                 if (!f.getDescriptor().equals(type.toMethodDescriptorString())) {
  90                     throw new RuntimeException("Expected: " + type.toMethodDescriptorString()
  91                         + " got: " + f.getDescriptor());
  92                 }
  93 
  94                 if (!f.getMethodType().equals(type)) {
  95                     throw new RuntimeException("Expected: " + type
  96                         + " got: " + f.getMethodType());
  97                 }
  98             }
  99         }
 100     }
 101 
 102     private final int depth;
 103     Basic(int depth) {
 104         this.depth = depth;
 105     }
 106 
 107     /*
 108      * Setup a stack builder with the expected stack depth
 109      * Walk the stack and count the frames.
 110      */
 111     void walk(int estimate) {
 112         int limit = Math.min(depth, 16);
 113         List<StackFrame> frames = new StackBuilder(depth, limit).build();
 114         System.out.format("depth=%d estimate=%d expected=%d walked=%d%n",
 115                           depth, estimate, limit, frames.size());
 116         assertEquals(limit, frames.size());
 117     }
 118 
 119     static class ConstructorNewInstance {
 120         static final StackWalker walker =
 121             StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE);


 140                 return true;
 141             }
 142             // Filter out all other frames (in particular
 143             // those from the test framework) in order to
 144             // have predictable results.
 145             return false;
 146         }
 147         public String frame(StackFrame f) {
 148             return f.getClassName() + "::" + f.getMethodName();
 149         }
 150         List<String> parse(Stream<StackFrame> s) {
 151             return s.filter(this::accept)
 152                     .map(this::frame)
 153                     .collect(Collectors.toList());
 154         }
 155         public static ConstructorNewInstance create() throws Exception {
 156             return ConstructorNewInstance.class.getConstructor().newInstance();
 157         }
 158     }
 159 
 160     static class StackBuilder {
 161         private final int stackDepth;
 162         private final int limit;
 163         private int depth = 0;
 164         private List<StackFrame> result;
 165         StackBuilder(int stackDepth, int limit) {
 166             this.stackDepth = stackDepth; // build method;
 167             this.limit = limit;
 168         }
 169         List<StackFrame> build() {
 170             trace("build");
 171             m1();
 172             return result;
 173         }
 174         void m1() {
 175             trace("m1");
 176             m2();
 177         }
 178         List m2() {
 179             trace("m2");
 180             m3();
 181             return null;
 182         }
 183         int m3() {
 184             trace("m3");
 185             m4(null);
 186             return 0;
 187         }
 188         void m4(Object o) {
 189             trace("m4");
 190             int remaining = stackDepth-depth-1;
 191             if (remaining >= 4) {
 192                 m1();
 193             } else {
 194                 filler(remaining);
 195             }
 196         }
 197         void filler(int i) {
 198             trace("filler");
 199             if (i == 0)
 200                 walk();
 201             else
 202                 filler(--i);
 203         }
 204 
 205         void walk() {
 206             StackWalker walker = StackWalker.getInstance(RETAIN_CLASS_REFERENCE);
 207             result = walker.walk(s -> s.limit(limit).collect(Collectors.toList()));
 208         }
 209         void trace(String methodname) {
 210             ++depth;
 211             if (verbose)
 212                 System.out.format("%2d: %s%n", depth, methodname);
 213         }
 214 
 215         static Map<String, MethodType> methodTypes() throws Exception {
 216             Map<String, MethodType> methodTypes = new HashMap<>();
 217             methodTypes.put("m1", MethodType.methodType(void.class));
 218             methodTypes.put("m2", MethodType.methodType(List.class));
 219             methodTypes.put("m3",MethodType.methodType(int.class));
 220             methodTypes.put("m4",  MethodType.methodType(void.class, Object.class));
 221             return methodTypes;
 222         }
 223     }
 224 
 225 }
< prev index next >