test/jdk/jdk/jfr/event/runtime/TestExceptionEvents.java
changeset 50113 caf115bb98ad
child 51214 67736b4846a0
equal deleted inserted replaced
50112:7a2a740815b7 50113:caf115bb98ad
       
     1 /*
       
     2  * Copyright (c) 2013, 2018, 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.  Oracle designates this
       
     8  * particular file as subject to the "Classpath" exception as provided
       
     9  * by Oracle in the LICENSE file that accompanied this code.
       
    10  *
       
    11  * This code is distributed in the hope that it will be useful, but WITHOUT
       
    12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
       
    13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
       
    14  * version 2 for more details (a copy is included in the LICENSE file that
       
    15  * accompanied this code).
       
    16  *
       
    17  * You should have received a copy of the GNU General Public License version
       
    18  * 2 along with this work; if not, write to the Free Software Foundation,
       
    19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
       
    20  *
       
    21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
       
    22  * or visit www.oracle.com if you need additional information or have any
       
    23  * questions.
       
    24  */
       
    25 
       
    26 package jdk.jfr.event.runtime;
       
    27 
       
    28 import java.time.Duration;
       
    29 import java.util.List;
       
    30 
       
    31 import jdk.jfr.Recording;
       
    32 import jdk.jfr.consumer.RecordedClass;
       
    33 import jdk.jfr.consumer.RecordedEvent;
       
    34 import jdk.jfr.consumer.RecordedFrame;
       
    35 import jdk.jfr.consumer.RecordedStackTrace;
       
    36 import jdk.jfr.consumer.RecordedThread;
       
    37 import jdk.test.lib.Asserts;
       
    38 import jdk.test.lib.jfr.EventNames;
       
    39 import jdk.test.lib.jfr.Events;
       
    40 
       
    41 /*
       
    42  * @test
       
    43  * @key jfr
       
    44  * @library /test/lib
       
    45  * @run main/othervm jdk.jfr.event.runtime.TestExceptionEvents
       
    46  */
       
    47 public class TestExceptionEvents {
       
    48 
       
    49     private static final String EXCEPTION_EVENT_PATH = EventNames.JavaExceptionThrow;
       
    50     private static final String ERROR_EVENT_PATH  = EventNames.JavaErrorThrow;
       
    51     private static final String EXCEPTION_STATISTICS_PATH = EventNames.ExceptionStatistics;
       
    52 
       
    53     private static final String EXCEPTION_MESSAGE = "exceptiontest";
       
    54     private static final String ERROR_MESSAGE = "errortest";
       
    55     private static final String THROWABLE_MESSAGE = "throwabletest";
       
    56 
       
    57     private static final int ITERATIONS = 10;
       
    58 
       
    59     private static int exceptionCount = 0;
       
    60 
       
    61     public static void main(String[] args) throws Throwable {
       
    62         Recording recording = createRecording();
       
    63 
       
    64         List<RecordedEvent> events = Events.fromRecording(recording);
       
    65         checkStatisticsEvent(events, exceptionCount);
       
    66         checkThrowableEvents(events, EXCEPTION_EVENT_PATH, ITERATIONS, MyException.class, EXCEPTION_MESSAGE);
       
    67         checkThrowableEvents(events, ERROR_EVENT_PATH, ITERATIONS, MyError.class, ERROR_MESSAGE);
       
    68         checkThrowableEvents(events, EXCEPTION_EVENT_PATH, ITERATIONS, MyThrowable.class, THROWABLE_MESSAGE);
       
    69         checkExceptionStackTrace();
       
    70     }
       
    71 
       
    72     private static void checkExceptionStackTrace() throws Exception {
       
    73         @SuppressWarnings("serial")
       
    74         class TestError extends Error {
       
    75         }
       
    76         @SuppressWarnings("serial")
       
    77         class TestException extends Exception {
       
    78         }
       
    79 
       
    80         try (Recording r = new Recording()) {
       
    81             r.enable(EventNames.JavaErrorThrow).withStackTrace();
       
    82             r.enable(EventNames.JavaExceptionThrow).withStackTrace();
       
    83             r.start();
       
    84             try {
       
    85                 throw new TestError();
       
    86             } catch (Error e) {
       
    87                 System.out.println(e.getClass() + " thrown!");
       
    88             }
       
    89             try {
       
    90                 throw new TestException();
       
    91             } catch (Exception e) {
       
    92                 System.out.println(e.getClass() + " thrown!");
       
    93             }
       
    94             try {
       
    95                 throw new Exception();
       
    96             } catch (Exception e) {
       
    97                 System.out.println(e.getClass() + " thrown!");
       
    98             }
       
    99             r.stop();
       
   100             List<RecordedEvent> events = Events.fromRecording(r);
       
   101             Events.hasEvents(events);
       
   102             for (RecordedEvent e : events) {
       
   103                 RecordedStackTrace rs = e.getStackTrace();
       
   104                 RecordedClass rc = e.getValue("thrownClass");
       
   105                 List<RecordedFrame> frames = rs.getFrames();
       
   106                 RecordedFrame topFrame = frames.get(0);
       
   107                 System.out.println(rc.getName() + " Top frame: " + topFrame.getMethod().getName());
       
   108                 if (!topFrame.getMethod().getName().equals("<init>")) {
       
   109                     throw new Exception("Expected name of top frame to be <init>");
       
   110                 }
       
   111             }
       
   112         }
       
   113     }
       
   114 
       
   115     private static Recording createRecording() throws Exception {
       
   116         Recording recording = new Recording();
       
   117         recording.enable(EXCEPTION_STATISTICS_PATH);
       
   118         recording.enable(EXCEPTION_EVENT_PATH).withThreshold(Duration.ofMillis(0));
       
   119         recording.enable(ERROR_EVENT_PATH).withThreshold(Duration.ofMillis(0));
       
   120         recording.start();
       
   121 
       
   122         for (int i = 0; i < ITERATIONS; i++) {
       
   123             try {
       
   124                 throw new MyException(EXCEPTION_MESSAGE);
       
   125             } catch (MyException e) {
       
   126                 exceptionCount++;
       
   127             }
       
   128             try {
       
   129                 throw new MyError(ERROR_MESSAGE);
       
   130             } catch (MyError e) {
       
   131                 exceptionCount++;
       
   132             }
       
   133             try {
       
   134                 throw new MyThrowable(THROWABLE_MESSAGE);
       
   135             } catch (MyThrowable t) {
       
   136                 exceptionCount++;
       
   137             }
       
   138         }
       
   139         recording.stop();
       
   140         return recording;
       
   141     }
       
   142 
       
   143 
       
   144     private static void checkStatisticsEvent(List<RecordedEvent> events, long minCount) throws Exception {
       
   145         // Events are not guaranteed to be in chronological order, take highest value.
       
   146         long count = -1;
       
   147         for(RecordedEvent event : events) {
       
   148             if (Events.isEventType(event, EXCEPTION_STATISTICS_PATH)) {
       
   149                 System.out.println("Event: " + event);
       
   150                 count = Math.max(count, Events.assertField(event, "throwables").getValue());
       
   151                 System.out.println("count=" +  count);
       
   152             }
       
   153         }
       
   154         Asserts.assertTrue(count != -1, "No events of type " + EXCEPTION_STATISTICS_PATH);
       
   155         Asserts.assertGreaterThanOrEqual(count, minCount, "Too few exception count in statistics event");
       
   156     }
       
   157 
       
   158     private static void checkThrowableEvents(List<RecordedEvent> events, String eventName,
       
   159         int excpectedEvents, Class<?> expectedClass, String expectedMessage) throws Exception {
       
   160         int count = 0;
       
   161         for(RecordedEvent event : events) {
       
   162             if (Events.isEventType(event, eventName)) {
       
   163                 String message = Events.assertField(event, "message").getValue();
       
   164                 if (expectedMessage.equals(message)) {
       
   165                     RecordedThread t = event.getThread();
       
   166                     String threadName = t.getJavaName();
       
   167                     if (threadName != null && threadName.equals(Thread.currentThread().getName())) {
       
   168                         RecordedClass jc = event.getValue("thrownClass");
       
   169                         if (jc.getName().equals(expectedClass.getName())) {
       
   170                             count++;
       
   171                         }
       
   172                     }
       
   173                 }
       
   174             }
       
   175         }
       
   176         Asserts.assertEquals(count, excpectedEvents, "Wrong event count for type " + eventName);
       
   177     }
       
   178 
       
   179     private static class MyException extends Exception {
       
   180         private static final long serialVersionUID = -2614309279743448910L;
       
   181         public MyException(String msg) {
       
   182             super(msg);
       
   183         }
       
   184     }
       
   185 
       
   186     private static class MyError extends Error {
       
   187         private static final long serialVersionUID = -8519872786387358196L;
       
   188         public MyError(String msg) {
       
   189             super(msg);
       
   190         }
       
   191     }
       
   192 
       
   193     private static class MyThrowable extends Throwable {
       
   194         private static final long serialVersionUID = -7929442863511070361L;
       
   195         public MyThrowable(String msg) {
       
   196             super(msg);
       
   197         }
       
   198     }
       
   199 }