/* * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package jdk.jfr.event.runtime; import java.util.HashMap; import java.util.List; import java.util.Map; import jdk.jfr.Configuration; import jdk.jfr.Event; import jdk.jfr.EventType; import jdk.jfr.FlightRecorder; import jdk.jfr.Recording; import jdk.jfr.Registered; import jdk.jfr.SettingDescriptor; import jdk.jfr.consumer.RecordedEvent; import jdk.test.lib.Asserts; import jdk.test.lib.jfr.EventNames; import jdk.test.lib.jfr.Events; /** * @test * @summary Tests that active setting are available in the ActiveSettingevent * @key jfr * @requires vm.hasJFR * @library /test/lib * @run main/othervm jdk.jfr.event.runtime.TestActiveSettingEvent */ public final class TestActiveSettingEvent { private static class MyEvent extends Event { } @Registered(false) private static class MyRegistrationEvent extends Event { } private static final String ACTIVE_SETTING_EVENT_NAME = EventNames.ActiveSetting; public static void main(String[] args) throws Throwable { testDefaultSettings();; testProfileSettings();; testNewSettings(); testChangedSetting(); testUnregistered(); testRegistration(); } private static void testProfileSettings() throws Exception { testSettingConfiguration("profile"); } private static void testDefaultSettings() throws Exception { testSettingConfiguration("default"); } private static void testRegistration() throws Exception { // Register new try (Recording recording = new Recording()) { recording.enable(ACTIVE_SETTING_EVENT_NAME); recording.start(); FlightRecorder.register(MyRegistrationEvent.class); recording.stop(); List events = Events.fromRecording(recording); Events.hasEvents(events); EventType type = EventType.getEventType(MyRegistrationEvent.class); assertSetting(events, type, "threshold", "0 ns"); assertSetting(events, type, "enabled", "true"); assertSetting(events, type, "stackTrace", "true"); } // Register unregistered FlightRecorder.unregister(MyEvent.class); try (Recording recording = new Recording()) { recording.enable(ACTIVE_SETTING_EVENT_NAME); recording.start(); FlightRecorder.register(MyRegistrationEvent.class); recording.stop(); EventType type = EventType.getEventType(MyRegistrationEvent.class); List events = Events.fromRecording(recording); Events.hasEvents(events); type = EventType.getEventType(MyRegistrationEvent.class); assertSetting(events, type, "threshold", "0 ns"); assertSetting(events, type, "enabled", "true"); assertSetting(events, type, "stackTrace", "true"); } } private static void testUnregistered() throws Exception { FlightRecorder.register(MyEvent.class); EventType type = EventType.getEventType(MyEvent.class); FlightRecorder.unregister(MyEvent.class); try (Recording recording = new Recording()) { recording.enable(ACTIVE_SETTING_EVENT_NAME); recording.start(); MyEvent m = new MyEvent(); m.commit(); recording.stop(); List events = Events.fromRecording(recording); Events.hasEvents(events); assertNotSetting(events, type, "threshold", "0 ns"); assertNotSetting(events, type, "enabled", "true"); assertNotSetting(events, type, "stackTrace", "true"); } } private static void testNewSettings() throws Exception { try (Recording recording = new Recording()) { recording.enable(ACTIVE_SETTING_EVENT_NAME); recording.start(); MyEvent m = new MyEvent(); m.commit(); recording.stop(); List events = Events.fromRecording(recording); Events.hasEvents(events); EventType type = EventType.getEventType(MyEvent.class); assertSetting(events, type, "threshold", "0 ns"); assertSetting(events, type, "enabled", "true"); assertSetting(events, type, "stackTrace", "true"); assertNotSetting(events, type, "period", "everyChunk"); } } private static void testChangedSetting() throws Exception { EventType type = EventType.getEventType(MyEvent.class); Map base = new HashMap<>(); base.put(ACTIVE_SETTING_EVENT_NAME + "#enabled", "true"); try (Recording recording = new Recording()) { recording.setSettings(base); recording.start(); Map newS = new HashMap<>(base); newS.put(type.getName() + "#enabled", "true"); newS.put(type.getName() + "#threshold", "11 ns"); recording.setSettings(newS); recording.stop(); List events = Events.fromRecording(recording); Events.hasEvents(events); assertSetting(events, type, "threshold", "0 ns"); // initial value assertSetting(events, type, "enabled", "true"); assertSetting(events, type, "threshold", "11 ns"); // changed value } } private static void assertSetting(List events, EventType evenType, String settingName, String settingValue) throws Exception { if (!hasSetting(events, evenType, settingName, settingValue)) { throw new Exception("Could not find setting " + settingName + " with value " + settingValue + " for event type " + evenType.getName()); } } private static void assertNotSetting(List events, EventType evenType, String settingName, String settingValue) throws Exception { if (hasSetting(events, evenType, settingName, settingValue)) { throw new Exception("Found unexpected setting " + settingName + " with value " + settingValue + " for event type " + evenType.getName()); } } private static boolean hasSetting(List events, EventType evenType, String settingName, String settingValue) throws Exception { for (RecordedEvent e : events) { if (e.getEventType().getName().equals(ACTIVE_SETTING_EVENT_NAME)) { String name = e.getValue("name"); String value = e.getValue("value"); Long id = e.getValue("id"); if (evenType.getId() == id && name.equals(settingName) && settingValue.equals(value)) { return true; } } } return false; } private static void testSettingConfiguration(String configurationName) throws Exception { System.out.println("Testing configuration " + configurationName); Configuration c = Configuration.getConfiguration(configurationName); Map settingValues = c.getSettings(); // Don't want to add these settings to the jfc-files we ship since they // are not useful to configure. They are however needed to make the test // pass. settingValues.put(EventNames.ActiveSetting + "#stackTrace", "false"); settingValues.put(EventNames.ActiveSetting + "#threshold", "0 ns"); settingValues.put(EventNames.ActiveRecording + "#stackTrace", "false"); settingValues.put(EventNames.ActiveRecording + "#threshold", "0 ns"); settingValues.put(EventNames.JavaExceptionThrow + "#threshold", "0 ns"); settingValues.put(EventNames.JavaErrorThrow + "#threshold", "0 ns"); try (Recording recording = new Recording(c)) { Map eventTypes = new HashMap<>(); for (EventType et : FlightRecorder.getFlightRecorder().getEventTypes()) { eventTypes.put(et.getId(), et); } recording.start(); Map expectedSettings = new HashMap<>(); for (EventType type : FlightRecorder.getFlightRecorder().getEventTypes()) { for (SettingDescriptor s : type.getSettingDescriptors()) { String settingName = type.getName() + "#" + s.getName(); String value = settingValues.get(settingName); if (value == null) { throw new Exception("Could not find setting with name " + settingName); } // Prefer to have ms unit in jfc file if (value.equals("0 ms")) { value = "0 ns"; } expectedSettings.put(settingName, value); } } recording.stop(); for (RecordedEvent e : Events.fromRecording(recording)) { if (e.getEventType().getName().equals(ACTIVE_SETTING_EVENT_NAME)) { Long id = e.getValue("id"); EventType et = eventTypes.get(id); if (et == null) { throw new Exception("Could not find event type with id " + id); } String name = e.getValue("name"); String settingName = et.getName() + "#" + name; String value = e.getValue("value"); String expectedValue = expectedSettings.get(settingName); if (expectedValue != null) { if (value.equals("0 ms")) { value = "0 ns"; } Asserts.assertEquals(expectedValue, value, "Incorrect settings value for " + settingName + " was " + value + ", expected " + expectedValue); expectedSettings.remove(settingName); } } } if (!expectedSettings.isEmpty()) { throw new Exception("Not all setting in event. Missing " + expectedSettings.keySet()); } } } }