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