1 /*
   2  * Copyright (c) 2018, 2019, 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 test.jfr.main;
  27 
  28 import java.io.File;
  29 import java.io.IOException;
  30 import java.util.List;
  31 
  32 import jdk.jfr.AnnotationElement;
  33 import jdk.jfr.EventType;
  34 import jdk.jfr.FlightRecorder;
  35 import jdk.jfr.Recording;
  36 import jdk.jfr.ValueDescriptor;
  37 import jdk.jfr.consumer.RecordedEvent;
  38 
  39 import test.jfr.annotation.ModularizedAnnotation;
  40 import test.jfr.event.ModularizedOrdinaryEvent;
  41 import test.jfr.event.ModularizedPeriodicEvent;
  42 import java.nio.file.Path;
  43 import java.util.Objects;
  44 import jdk.jfr.consumer.RecordingFile;
  45 
  46 public class MainTest {
  47 
  48     private static final String HELLO_ORDINARY = "ordinary says hello";
  49     private static final String HELLO_PERIODIC = "periodic says hello";
  50 
  51     public static void main(String... args) throws Exception {
  52         System.out.println("Starting the test...");
  53         FlightRecorder.addPeriodicEvent(ModularizedPeriodicEvent.class, () -> {
  54             ModularizedPeriodicEvent me = new ModularizedPeriodicEvent();
  55             me.message = HELLO_PERIODIC;
  56             me.commit();
  57         });
  58         Recording r = new Recording();
  59         r.enable(ModularizedOrdinaryEvent.class).with("filter", "true").withoutStackTrace();
  60         r.enable(ModularizedPeriodicEvent.class).with("filter", "true").withoutStackTrace();
  61         r.start();
  62         ModularizedOrdinaryEvent m = new ModularizedOrdinaryEvent();
  63         m.message = HELLO_ORDINARY;
  64         m.commit();
  65         r.stop();
  66         List<RecordedEvent> events = fromRecording(r);
  67         System.out.println(events);
  68         if (events.size() == 0) {
  69             throw new RuntimeException("Expected two events");
  70         }
  71         assertOrdinaryEvent(events);
  72         assertPeriodicEvent(events);
  73         assertMetadata(events);
  74         System.out.println("Test passed.");
  75     }
  76 
  77     private static void assertMetadata(List<RecordedEvent> events) {
  78         for (RecordedEvent e : events) {
  79             EventType type = e.getEventType();
  80             ModularizedAnnotation maType = type.getAnnotation(ModularizedAnnotation.class);
  81             if (maType == null) {
  82                 fail("Missing @ModularizedAnnotation on type " + type);
  83             }
  84             assertEquals(maType.value(), "hello type");
  85             assertMetaAnnotation(type.getAnnotationElements());
  86 
  87             ValueDescriptor messageField = type.getField("message");
  88             ModularizedAnnotation maField = messageField.getAnnotation(ModularizedAnnotation.class);
  89             if (maField == null) {
  90                 fail("Missing @ModularizedAnnotation on field in " + type);
  91             }
  92             assertEquals(maField.value(), "hello field");
  93             assertMetaAnnotation(messageField.getAnnotationElements());
  94         }
  95     }
  96 
  97     private static void assertMetaAnnotation(List<AnnotationElement> aes) {
  98         assertEquals(aes.size(), 1, "@ModularizedAnnotation should only have one meta-annotation");
  99         AnnotationElement ae = aes.get(0);
 100         assertEquals(ae.getTypeName(), ModularizedAnnotation.class.getName(), "Incorrect meta-annotation");
 101     }
 102 
 103     private static void assertPeriodicEvent(List<RecordedEvent> events) {
 104         for (RecordedEvent e : events) {
 105             String message = e.getValue("message");
 106             if (message.equals(HELLO_ORDINARY)) {
 107                 return;
 108             }
 109         }
 110         throw new RuntimeException("Could not find ordinary event in recording");
 111     }
 112 
 113     private static void assertOrdinaryEvent(List<RecordedEvent> events) {
 114         for (RecordedEvent e : events) {
 115             String message = e.getValue("message");
 116             if (message.equals(HELLO_PERIODIC)) {
 117                 return;
 118             }
 119         }
 120         throw new RuntimeException("Could not find periodic event in recording");
 121     }
 122 
 123     public static List<RecordedEvent> fromRecording(Recording recording) throws IOException {
 124         return RecordingFile.readAllEvents(makeCopy(recording));
 125     }
 126 
 127     private static Path makeCopy(Recording recording) throws IOException {
 128         Path p = recording.getDestination();
 129         if (p == null) {
 130             File directory = new File(".");
 131             ProcessHandle h = ProcessHandle.current();
 132             p = new File(directory.getAbsolutePath(), "recording-" + recording.getId() + "-pid" + h.pid() + ".jfr").toPath();
 133             recording.dump(p);
 134         }
 135         return p;
 136     }
 137 
 138     private static void assertEquals(Object lhs, Object rhs) {
 139         assertEquals(lhs, rhs, null);
 140     }
 141 
 142     private static void assertEquals(Object lhs, Object rhs, String msg) {
 143         if ((lhs != rhs) && ((lhs == null) || !(lhs.equals(rhs)))) {
 144             msg = Objects.toString(msg, "assertEquals")
 145                     + ": expected " + Objects.toString(lhs)
 146                     + " to equal " + Objects.toString(rhs);
 147             fail(msg);
 148         }
 149     }
 150 
 151     private static void fail(String message) {
 152         throw new RuntimeException(message);
 153     }
 154 }