1 /* 2 * Copyright (c) 2017, 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.event.runtime; 26 27 import java.util.HashMap; 28 import java.util.List; 29 import java.util.Map; 30 31 import jdk.jfr.Configuration; 32 import jdk.jfr.Event; 33 import jdk.jfr.EventType; 34 import jdk.jfr.FlightRecorder; 35 import jdk.jfr.Recording; 36 import jdk.jfr.Registered; 37 import jdk.jfr.SettingDescriptor; 38 import jdk.jfr.consumer.RecordedEvent; 39 import jdk.test.lib.Asserts; 40 import jdk.test.lib.jfr.EventNames; 41 import jdk.test.lib.jfr.Events; 42 43 /* 44 * @test 45 * @summary Tests that active setting are available in the ActiveSettingevent 46 * @key jfr 47 * @library /test/lib 48 * @run main/othervm jdk.jfr.event.runtime.TestActiveSettingEvent 49 */ 50 public final class TestActiveSettingEvent { 51 52 private static class MyEvent extends Event { 53 } 54 55 @Registered(false) 56 private static class MyRegistrationEvent extends Event { 57 } 58 59 private static final String ACTIVE_SETTING_EVENT_NAME = EventNames.ActiveSetting; 60 61 public static void main(String[] args) throws Throwable { 62 testDefaultSettings();; 63 testProfileSettings();; 64 testNewSettings(); 65 testChangedSetting(); 66 testUnregistered(); 67 testRegistration(); 68 } 69 70 private static void testProfileSettings() throws Exception { 71 testSettingConfiguration("profile"); 72 } 73 74 private static void testDefaultSettings() throws Exception { 75 testSettingConfiguration("default"); 76 } 77 78 private static void testRegistration() throws Exception { 79 // Register new 80 try (Recording recording = new Recording()) { 81 recording.enable(ACTIVE_SETTING_EVENT_NAME); 82 recording.start(); 83 FlightRecorder.register(MyRegistrationEvent.class); 84 recording.stop(); 85 List<RecordedEvent> events = Events.fromRecording(recording); 86 Events.hasEvents(events); 87 EventType type = EventType.getEventType(MyRegistrationEvent.class); 88 assertSetting(events, type, "threshold", "0 ns"); 89 assertSetting(events, type, "enabled", "true"); 90 assertSetting(events, type, "stackTrace", "true"); 91 } 92 // Register unregistered 93 FlightRecorder.unregister(MyEvent.class); 94 try (Recording recording = new Recording()) { 95 recording.enable(ACTIVE_SETTING_EVENT_NAME); 96 recording.start(); 97 FlightRecorder.register(MyRegistrationEvent.class); 98 recording.stop(); 99 EventType type = EventType.getEventType(MyRegistrationEvent.class); 100 List<RecordedEvent> events = Events.fromRecording(recording); 101 Events.hasEvents(events); 102 type = EventType.getEventType(MyRegistrationEvent.class); 103 assertSetting(events, type, "threshold", "0 ns"); 104 assertSetting(events, type, "enabled", "true"); 105 assertSetting(events, type, "stackTrace", "true"); 106 } 107 } 108 109 private static void testUnregistered() throws Exception { 110 FlightRecorder.register(MyEvent.class); 111 EventType type = EventType.getEventType(MyEvent.class); 112 FlightRecorder.unregister(MyEvent.class); 113 try (Recording recording = new Recording()) { 114 recording.enable(ACTIVE_SETTING_EVENT_NAME); 115 recording.start(); 116 MyEvent m = new MyEvent(); 117 m.commit(); 118 recording.stop(); 119 List<RecordedEvent> events = Events.fromRecording(recording); 120 Events.hasEvents(events); 121 assertNotSetting(events, type, "threshold", "0 ns"); 122 assertNotSetting(events, type, "enabled", "true"); 123 assertNotSetting(events, type, "stackTrace", "true"); 124 } 125 } 126 127 private static void testNewSettings() throws Exception { 128 try (Recording recording = new Recording()) { 129 recording.enable(ACTIVE_SETTING_EVENT_NAME); 130 recording.start(); 131 MyEvent m = new MyEvent(); 132 m.commit(); 133 recording.stop(); 134 List<RecordedEvent> events = Events.fromRecording(recording); 135 Events.hasEvents(events); 136 EventType type = EventType.getEventType(MyEvent.class); 137 assertSetting(events, type, "threshold", "0 ns"); 138 assertSetting(events, type, "enabled", "true"); 139 assertSetting(events, type, "stackTrace", "true"); 140 assertNotSetting(events, type, "period", "everyChunk"); 141 } 142 } 143 144 private static void testChangedSetting() throws Exception { 145 EventType type = EventType.getEventType(MyEvent.class); 146 Map<String, String> base = new HashMap<>(); 147 base.put(ACTIVE_SETTING_EVENT_NAME + "#enabled", "true"); 148 try (Recording recording = new Recording()) { 149 recording.setSettings(base); 150 recording.start(); 151 Map<String, String> newS = new HashMap<>(base); 152 newS.put(type.getName() + "#enabled", "true"); 153 newS.put(type.getName() + "#threshold", "11 ns"); 154 recording.setSettings(newS); 155 recording.stop(); 156 List<RecordedEvent> events = Events.fromRecording(recording); 157 Events.hasEvents(events); 158 assertSetting(events, type, "threshold", "0 ns"); // initial value 159 assertSetting(events, type, "enabled", "true"); 160 assertSetting(events, type, "threshold", "11 ns"); // changed value 161 } 162 } 163 164 private static void assertSetting(List<RecordedEvent> events, EventType evenType, String settingName, String settingValue) throws Exception { 165 if (!hasSetting(events, evenType, settingName, settingValue)) { 166 throw new Exception("Could not find setting " + settingName + " with value " + settingValue + " for event type " + evenType.getName()); 167 } 168 } 169 170 private static void assertNotSetting(List<RecordedEvent> events, EventType evenType, String settingName, String settingValue) throws Exception { 171 if (hasSetting(events, evenType, settingName, settingValue)) { 172 throw new Exception("Found unexpected setting " + settingName + " with value " + settingValue + " for event type " + evenType.getName()); 173 } 174 } 175 176 private static boolean hasSetting(List<RecordedEvent> events, EventType evenType, String settingName, String settingValue) throws Exception { 177 for (RecordedEvent e : events) { 178 if (e.getEventType().getName().equals(ACTIVE_SETTING_EVENT_NAME)) { 179 String name = e.getValue("name"); 180 String value = e.getValue("value"); 181 Long id = e.getValue("id"); 182 if (evenType.getId() == id && name.equals(settingName) && settingValue.equals(value)) { 183 return true; 184 } 185 } 186 } 187 return false; 188 } 189 190 private static void testSettingConfiguration(String configurationName) throws Exception { 191 System.out.println("Testing configuration " + configurationName); 192 Configuration c = Configuration.getConfiguration(configurationName); 193 Map<String, String> settingValues = c.getSettings(); 194 // Don't want to add these settings to the jfc-files we ship since they 195 // are not useful to configure. They are however needed to make the test 196 // pass. 197 settingValues.put("com.oracle.jdk.ActiveSetting#stackTrace", "false"); 198 settingValues.put("com.oracle.jdk.ActiveSetting#threshold", "0 ns"); 199 settingValues.put("com.oracle.jdk.ActiveRecording#stackTrace", "false"); 200 settingValues.put("com.oracle.jdk.ActiveRecording#threshold", "0 ns"); 201 settingValues.put("com.oracle.jdk.JavaExceptionThrow#threshold", "0 ns"); 202 settingValues.put("com.oracle.jdk.JavaErrorThrow#threshold", "0 ns"); 203 204 try (Recording recording = new Recording(c)) { 205 Map<Long, EventType> eventTypes = new HashMap<>(); 206 for (EventType et : FlightRecorder.getFlightRecorder().getEventTypes()) { 207 eventTypes.put(et.getId(), et); 208 } 209 recording.start(); 210 Map<String, String> expectedSettings = new HashMap<>(); 211 for (EventType type : FlightRecorder.getFlightRecorder().getEventTypes()) { 212 for (SettingDescriptor s : type.getSettingDescriptors()) { 213 String settingName = type.getName() + "#" + s.getName(); 214 String value = settingValues.get(settingName); 215 if (value == null) { 216 throw new Exception("Could not find setting with name " + settingName); 217 } 218 // Prefer to have ms unit in jfc file 219 if (value.equals("0 ms")) { 220 value = "0 ns"; 221 } 222 expectedSettings.put(settingName, value); 223 } 224 } 225 recording.stop(); 226 227 for (RecordedEvent e : Events.fromRecording(recording)) { 228 if (e.getEventType().getName().equals(ACTIVE_SETTING_EVENT_NAME)) { 229 Long id = e.getValue("id"); 230 EventType et = eventTypes.get(id); 231 if (et == null) { 232 throw new Exception("Could not find event type with id " + id); 233 } 234 String name = e.getValue("name"); 235 String settingName = et.getName() + "#" + name; 236 String value = e.getValue("value"); 237 String expectedValue = expectedSettings.get(settingName); 238 if (expectedValue != null) { 239 if (value.equals("0 ms")) { 240 value = "0 ns"; 241 } 242 Asserts.assertEquals(expectedValue, value, "Incorrect settings value for " + settingName + " was " + value + ", expected " + expectedValue); 243 expectedSettings.remove(settingName); 244 } 245 } 246 } 247 if (!expectedSettings.isEmpty()) { 248 throw new Exception("Not all setting in event. Missing " + expectedSettings.keySet()); 249 } 250 } 251 } 252 }