1 /* 2 * Copyright (c) 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 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 }