Path: blob/master/test/jdk/java/lang/StackWalker/StackStreamTest.java
41149 views
/*1* Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223import static java.lang.StackWalker.Option.*;24import java.lang.StackWalker.StackFrame;25import java.util.Arrays;26import java.util.List;27import java.util.Optional;28import java.util.logging.Logger;29import java.util.stream.Collectors;3031/**32* @test33* @bug 814045034* @summary Stack Stream Test35* @modules java.logging36* @run main/othervm StackStreamTest37*/38public class StackStreamTest {39public static void main(String[] argv) throws Exception {40new StackStreamTest().test();41}4243private static Logger logger = Logger.getLogger("stackstream");44public StackStreamTest() {45}4647public void test() {48A.a();49}50static class A {51public static void a() {52B.b();53}54}55static class B {56public static void b() {57C.c();58}59}60static class C {61public static void c() {62D.d();63}64}65static class D {66public static void d() {67E.e();68}69}70static class E {71public static void e() {72F.f();73}74}75static class F {76public static void f() {77logger.severe("log message");78G.g();79new K().k();80}81}8283private static boolean isTestClass(StackFrame f) {84// Filter jtreg frames from the end of the stack85return f.getClassName().startsWith("StackStreamTest");86}8788static class G {89static StackWalker STE_WALKER = StackWalker.getInstance();90static StackWalker DEFAULT_WALKER = StackWalker.getInstance();9192private static final List<String> GOLDEN_CLASS_NAMES =93Arrays.asList("StackStreamTest$G",94"StackStreamTest$F",95"StackStreamTest$E",96"StackStreamTest$D",97"StackStreamTest$C",98"StackStreamTest$B",99"StackStreamTest$A",100"StackStreamTest",101"StackStreamTest");102private static final List<String> GOLDEN_METHOD_NAMES =103Arrays.asList("g", "f", "e", "d", "c", "b", "a", "test", "main");104105106public static void g() {107108System.out.println("Thread dump");109Thread.dumpStack();110111caller();112firstFrame();113114// Check class names115System.out.println("check class names");116List<String> sfs = DEFAULT_WALKER.walk(s -> {117return s.filter(StackStreamTest::isTestClass)118.map(StackFrame::getClassName)119.collect(Collectors.toList());120});121equalsOrThrow("class names", sfs, GOLDEN_CLASS_NAMES);122123// Check method names124System.out.println("methodNames()");125sfs = DEFAULT_WALKER.walk(s -> {126return s.filter(StackStreamTest::isTestClass)127.map(StackFrame::getMethodName)128.collect(Collectors.toList());}129);130equalsOrThrow("method names", sfs, GOLDEN_METHOD_NAMES);131132Exception exc = new Exception("G.g stack");133exc.printStackTrace();134135System.out.println("Stream of StackTraceElement");136StackWalker.getInstance()137.walk(s ->138{139s.map(StackFrame::toStackTraceElement)140.forEach(ste -> System.out.println("STE: " + ste));141return null;142});143144// Do we need this?145System.out.println("Collect StackTraceElement");146List<StackTraceElement> stacktrace = STE_WALKER.walk(s ->147{148// Filter out jtreg frames149return s.filter(StackStreamTest::isTestClass)150.collect(Collectors.mapping(StackFrame::toStackTraceElement, Collectors.toList()));151});152int i=0;153for (StackTraceElement s : stacktrace) {154System.out.format(" %d: %s%n", i++, s);155}156157// Check STEs for correctness158checkStackTraceElements(GOLDEN_CLASS_NAMES, GOLDEN_METHOD_NAMES, stacktrace);159}160161static void checkStackTraceElements(List<String> classNames,162List<String> methodNames,163List<StackTraceElement> stes) {164if (classNames.size() != methodNames.size() ) {165throw new RuntimeException("Test error: classNames and methodNames should be same size");166}167if (classNames.size() != stes.size()) {168dumpSTEInfo(classNames, methodNames, stes);169throw new RuntimeException("wrong number of elements in stes");170}171for (int i = 0; i < classNames.size() ; i++) {172if (!classNames.get(i).equals(stes.get(i).getClassName()) ||173!methodNames.get(i).equals(stes.get(i).getMethodName())) {174dumpSTEInfo(classNames, methodNames, stes);175throw new RuntimeException("class & method names don't match");176}177}178}179180static void dumpSTEInfo(List<String> classNames, List<String> methodNames,181List<StackTraceElement> stes) {182System.out.println("Observed class, method names:");183for (StackTraceElement ste : stes) {184System.out.println(" " + ste.getClassName() + ", " + ste.getMethodName());185}186System.out.println("Expected class, method names:");187for (int i = 0; i < classNames.size(); i++) {188System.out.println(" " + classNames.get(i) + ", " + methodNames.get(i));189}190}191192static void firstFrame() {193System.out.println("first frame()");194StackWalker sw = StackWalker.getInstance(RETAIN_CLASS_REFERENCE);195sw.forEach(e -> {196System.out.println(e.getClassName() + "," + e.getMethodName());197});198System.out.println("\n");199Optional<StackFrame> frame = sw.walk(s ->200{201return s.filter(e -> {202System.err.println(e.getClassName() + " == " +203e.getClassName().equals("StackStreamTest"));204return e.getClassName().equals("StackStreamTest");205}).findFirst();206});207Class<?> c = frame.get().getDeclaringClass();208System.out.println("\nfirst frame: " + c);209if (c != StackStreamTest.class) {210throw new RuntimeException("Unexpected first caller class " + c);211}212}213}214215private static <T> void equalsOrThrow(String label, List<T> list, List<T> expected) {216System.out.println("List: " + list);217System.out.println("Expectd: " + list);218if (!list.equals(expected)) {219System.err.println("Observed " + label);220for (T s1 : list) {221System.out.println(" " + s1);222}223System.err.println("Expected " + label);224for (T s2 : expected) {225System.out.println(" " + s2);226}227throw new RuntimeException("Error with " + label);228}229}230231232static class K {233void k() {234k1();235}236void k1() {237k2();238}239void k2() {240k3();241}242void k3() {243k4();244}245void k4() {246k5();247}248void k5() {249k6();250}251void k6() {252k7();253}254void k7() {255k8();256}257void k8() {258k9();259}260void k9() {261k10();262}263void k10() {264k20();265}266void k20() {267new Caller().test();268}269270class Caller {271void test() {272Class<?> c = StackWalker.getInstance(RETAIN_CLASS_REFERENCE).getCallerClass();273System.out.println("\nTesting K class : " + c);274Thread.dumpStack();275if (c != K.class) {276throw new RuntimeException("Unexpected caller class "+ c);277}278}279}280}281282static void caller() {283Class<?> c = StackWalker.getInstance(RETAIN_CLASS_REFERENCE).getCallerClass();284System.out.println("\ncaller class : " + c);285if (c != G.class) {286throw new RuntimeException("Unexpected caller class "+ c);287}288}289290}291292293