1 /* 2 * Copyright (c) 2014, 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 package jdk.jfr.jvm; 26 27 28 import java.io.FileReader; 29 import java.io.IOException; 30 import java.nio.file.Files; 31 import java.nio.file.Path; 32 import java.nio.file.Paths; 33 import java.util.ArrayList; 34 import java.util.concurrent.Callable; 35 36 import jdk.jfr.AnnotationElement; 37 import jdk.jfr.Configuration; 38 import jdk.jfr.Description; 39 import jdk.jfr.Event; 40 import jdk.jfr.EventFactory; 41 import jdk.jfr.EventSettings; 42 import jdk.jfr.EventType; 43 import jdk.jfr.FlightRecorder; 44 import jdk.jfr.FlightRecorderListener; 45 import jdk.jfr.FlightRecorderPermission; 46 import jdk.jfr.Label; 47 import jdk.jfr.Recording; 48 import jdk.jfr.RecordingState; 49 import jdk.jfr.SettingControl; 50 import jdk.jfr.ValueDescriptor; 51 import jdk.jfr.consumer.RecordedClass; 52 import jdk.jfr.consumer.RecordedEvent; 53 import jdk.jfr.consumer.RecordedFrame; 54 import jdk.jfr.consumer.RecordedMethod; 55 import jdk.jfr.consumer.RecordedObject; 56 import jdk.jfr.consumer.RecordedStackTrace; 57 import jdk.jfr.consumer.RecordedThread; 58 import jdk.jfr.consumer.RecordedThreadGroup; 59 import jdk.jfr.consumer.RecordingFile; 60 import jdk.management.jfr.ConfigurationInfo; 61 import jdk.management.jfr.EventTypeInfo; 62 import jdk.management.jfr.FlightRecorderMXBean; 63 import jdk.management.jfr.RecordingInfo; 64 import jdk.management.jfr.SettingDescriptorInfo; 65 import jdk.test.lib.Utils; 66 67 /** 68 * @test TestUnsupportedVM 69 * @key jfr 70 * 71 * 72 * 73 * 74 * @library /lib / 75 * @run main/othervm -Dprepare-recording=true jdk.jfr.jvm.TestUnsupportedVM 76 * @run main/othervm -Djfr.unsupported.vm=true jdk.jfr.jvm.TestUnsupportedVM 77 */ 78 public class TestUnsupportedVM { 79 80 private static Path RECORDING_FILE = Paths.get("recording.jfr"); 81 private static Class<?> [] APIClasses = { 82 AnnotationElement.class, 83 Configuration.class, 84 ConfigurationInfo.class, 85 Event.class, 86 EventFactory.class, 87 EventSettings.class, 88 EventType.class, 89 EventTypeInfo.class, 90 FlightRecorder.class, 91 FlightRecorderPermission.class, 92 FlightRecorderListener.class, 93 FlightRecorderMXBean.class, 94 RecordedClass.class, 95 RecordedEvent.class, 96 RecordedFrame.class, 97 RecordedMethod.class, 98 RecordedObject.class, 99 RecordedStackTrace.class, 100 RecordedThread.class, 101 RecordedThreadGroup.class, 102 Recording.class, 103 RecordingFile.class, 104 RecordingInfo.class, 105 RecordingState.class, 106 SettingControl.class, 107 SettingDescriptorInfo.class, 108 ValueDescriptor.class 109 }; 110 // * @run main/othervm -Dprepare-recording=true jdk.jfr.jvm.TestUnsupportedVM 111 @Label("My Event") 112 @Description("My fine event") 113 static class MyEvent extends Event { 114 int myValue; 115 } 116 117 public static void main(String... args) throws Exception { 118 if (Boolean.getBoolean("prepare-recording")) { 119 Recording r = new Recording(Configuration.getConfiguration("default")); 120 r.start(); 121 r.stop(); 122 r.dump(RECORDING_FILE); 123 r.close(); 124 return; 125 } 126 127 System.out.println("jdk.jfr.unsupportedvm=" + System.getProperty("jdk.jfr.unsupportedvm")); 128 // Class FlightRecorder 129 if (FlightRecorder.isAvailable()) { 130 throw new AssertionError("JFR should not be available on an unsupported VM"); 131 } 132 133 if (FlightRecorder.isInitialized()) { 134 throw new AssertionError("JFR should not be initialized on an unsupported VM"); 135 } 136 137 assertIllegalStateException(() -> FlightRecorder.getFlightRecorder()); 138 assertSwallow(() -> FlightRecorder.addListener(new FlightRecorderListener() {})); 139 assertSwallow(() -> FlightRecorder.removeListener(new FlightRecorderListener() {})); 140 assertSwallow(() -> FlightRecorder.register(MyEvent.class)); 141 assertSwallow(() -> FlightRecorder.unregister(MyEvent.class)); 142 assertSwallow(() -> FlightRecorder.addPeriodicEvent(MyEvent.class, new Runnable() { public void run() {} })); 143 assertSwallow(() -> FlightRecorder.removePeriodicEvent(new Runnable() { public void run() {} })); 144 145 // Class Configuration 146 if (!Configuration.getConfigurations().isEmpty()) { 147 throw new AssertionError("Configuration files should not exist on an unsupported VM"); 148 } 149 Path jfcFile = Utils.createTempFile("empty", ".jfr"); 150 assertIOException(() -> Configuration.getConfiguration("default")); 151 assertIOException(() -> Configuration.create(jfcFile)); 152 assertIOException(() -> Configuration.create(new FileReader(jfcFile.toFile()))); 153 154 // Class EventType 155 assertInternalError(() -> EventType.getEventType(MyEvent.class)); 156 157 // Class EventFactory 158 assertInternalError(() -> EventFactory.create(new ArrayList<>(), new ArrayList<>())); 159 160 // Create a static event 161 MyEvent myEvent = new MyEvent(); 162 myEvent.begin(); 163 myEvent.end(); 164 myEvent.shouldCommit(); 165 myEvent.commit(); 166 167 // Trigger class initialization failure 168 for (Class<?> c : APIClasses) { 169 assertNoClassInitFailure(c); 170 } 171 172 // jdk.jfr.consumer.* 173 // Only run this part of tests if we are on VM 174 // that can produce a recording file 175 if (Files.exists(RECORDING_FILE)) { 176 for(RecordedEvent re : RecordingFile.readAllEvents(RECORDING_FILE)) { 177 System.out.println(re); 178 } 179 } 180 } 181 182 private static void assertNoClassInitFailure(Class<?> clazz) { 183 try { 184 Class.forName(clazz.getName(), true, clazz.getClassLoader()); 185 } catch (ClassNotFoundException e) { 186 throw new AssertionError("Could not find public API class on unsupported VM"); 187 } 188 } 189 190 private static void assertInternalError(Runnable r) { 191 try { 192 r.run(); 193 } catch (InternalError e) { 194 // OK, as expected 195 return; 196 } 197 throw new AssertionError("Expected InternalError on an unsupported JVM"); 198 } 199 200 private static void assertIOException(Callable<?> c) { 201 try { 202 c.call(); 203 } catch (Exception e) { 204 if (e.getClass() == IOException.class) { 205 return; 206 } 207 } 208 throw new AssertionError("Expected IOException on an unsupported JVM"); 209 } 210 211 private static void assertIllegalStateException(Runnable r) throws Exception { 212 try { 213 r.run(); 214 } catch (IllegalStateException ise) { 215 if (!ise.getMessage().equals("Flight Recorder is not supported on this VM")) { 216 throw new AssertionError("Expected 'Flight Recorder is not supported on this VM'"); 217 } 218 } 219 } 220 221 private static void assertSwallow(Runnable r) throws Exception { 222 try { 223 r.run(); 224 } catch (Exception e) { 225 throw new AssertionError("Unexpected exception '" + e.getMessage() + " on an unspported VM"); 226 } 227 } 228 }