--- /dev/null 2018-06-17 23:18:20.806999507 +0800 +++ new/test/lib/testlibrary/jdk/testlibrary/jfr/JmxHelper.java 2019-01-29 11:06:07.014248630 +0800 @@ -0,0 +1,281 @@ +/* + * Copyright (c) 2013, 2019, 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.testlibrary.jfr; + +import java.io.BufferedOutputStream; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.lang.management.ManagementFactory; +import java.time.Instant; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import jdk.jfr.EventType; +import jdk.jfr.FlightRecorder; +import jdk.jfr.Recording; +import jdk.jfr.RecordingState; +import jdk.jfr.SettingDescriptor; +import jdk.jfr.consumer.RecordedEvent; +import jdk.jfr.consumer.RecordingFile; +import jdk.management.jfr.EventTypeInfo; +import jdk.management.jfr.FlightRecorderMXBean; +import jdk.management.jfr.RecordingInfo; +import jdk.management.jfr.SettingDescriptorInfo; +import jdk.testlibrary.Asserts; +import jdk.testlibrary.jfr.CommonHelper; +import jdk.testlibrary.jfr.Events; + +public class JmxHelper { + + public static RecordingInfo getJmxRecording(long recId) { + for (RecordingInfo r : getFlighteRecorderMXBean().getRecordings()) { + if (r.getId() == recId) { + return r; + } + } + Asserts.fail("No RecordingInfo with id " + recId); + return null; + } + + public static Recording getJavaRecording(long recId) { + for (Recording r : FlightRecorder.getFlightRecorder().getRecordings()) { + if (r.getId() == recId) { + return r; + } + } + Asserts.fail("No Recording with id " + recId); + return null; + } + + public static void verifyState(long recId, RecordingState state, List recordings) { + RecordingInfo r = verifyExists(recId, recordings); + verifyState(r, state); + } + + public static void verifyState(RecordingInfo recording, RecordingState state) { + final String actual = recording.getState().toString(); + final String expected = state.toString(); + Asserts.assertEquals(actual, expected, "Wrong state"); + } + + public static void verifyState(long recId, RecordingState state, FlightRecorderMXBean bean) throws Exception { + FlightRecorder jfr = FlightRecorder.getFlightRecorder(); + Recording recording = CommonHelper.verifyExists(recId, jfr.getRecordings()); + CommonHelper.verifyRecordingState(recording, state); + verifyState(recId, state, bean.getRecordings()); + } + + public static void verifyNotExists(long recId, List recordings) { + for (RecordingInfo r : recordings) { + if (recId == r.getId()) { + logRecordingInfos(recordings); + Asserts.fail("Recording should not exist, id=" + recId); + } + } + } + + public static RecordingInfo verifyExists(long recId, List recordings) { + for (RecordingInfo r : recordings) { + if (recId == r.getId()) { + return r; + } + } + logRecordingInfos(recordings); + Asserts.fail("Recording not found, id=" + recId); + return null; + } + + + public static void logRecordingInfos(List recordings) { + System.out.println("RecordingInfos:"); + for (RecordingInfo r : recordings) { + System.out.println(asString(r)); + } + } + + public static void logRecordings(List recordings) { + System.out.println("Recordings:"); + for (Recording r : recordings) { + System.out.println(asString(r)); + } + } + + static File dump(long streamId, FlightRecorderMXBean bean) throws IOException { + File f = File.createTempFile("stream_" + streamId + "_", ".jfr", new File(".")); + try (FileOutputStream fos = new FileOutputStream(f); BufferedOutputStream bos = new BufferedOutputStream(fos)) { + while (true) { + byte[] data = bean.readStream(streamId); + if (data == null) { + bos.flush(); + return f; + } + bos.write(data); + } + } + } + + public static List parseStream(long streamId, FlightRecorderMXBean bean) throws Exception { + File dumpFile = dump(streamId, bean); + System.out.println("data.length=" + dumpFile.length()); + List events = new ArrayList<>(); + for (RecordedEvent event : RecordingFile.readAllEvents(dumpFile.toPath())) { + System.out.println("EVENT:" + event); + events.add(event); + } + return events; + } + + public static void verifyEquals(RecordingInfo ri, Recording r) { + String destination = r.getDestination() != null ? r.getDestination().toString() : null; + long maxAge = r.getMaxAge() != null ? r.getMaxAge().getSeconds() : 0; + long duration = r.getDuration() != null ? r.getDuration().getSeconds() : 0; + + Asserts.assertEquals(destination, ri.getDestination(), "Wrong destination"); + Asserts.assertEquals(r.getDumpOnExit(), ri.getDumpOnExit(), "Wrong dumpOnExit"); + Asserts.assertEquals(duration, ri.getDuration(), "Wrong duration"); + Asserts.assertEquals(r.getId(), ri.getId(), "Wrong id"); + Asserts.assertEquals(maxAge, ri.getMaxAge(), "Wrong maxAge"); + Asserts.assertEquals(r.getMaxSize(), ri.getMaxSize(), "Wrong maxSize"); + Asserts.assertEquals(r.getName(), ri.getName(), "Wrong name"); + Asserts.assertEquals(r.getSize(), ri.getSize(), "Wrong size"); + Asserts.assertEquals(toEpochMillis(r.getStartTime()), ri.getStartTime(), "Wrong startTime"); + Asserts.assertEquals(r.getState().toString(), ri.getState(), "Wrong state"); + Asserts.assertEquals(toEpochMillis(r.getStopTime()), ri.getStopTime(), "Wrong stopTime"); + + verifyMapEquals(r.getSettings(), ri.getSettings()); + } + + public static String asString(RecordingInfo r) { + StringBuffer sb = new StringBuffer(); + sb.append(String.format("RecordingInfo:%n")); + sb.append(String.format("destination=%s%n", r.getDestination())); + sb.append(String.format("dumpOnExit=%b%n", r.getDumpOnExit())); + sb.append(String.format("duration=%d%n", r.getDuration())); + sb.append(String.format("id=%d%n", r.getId())); + sb.append(String.format("maxAge=%d%n", r.getMaxAge())); + sb.append(String.format("maxSize=%d%n", r.getMaxSize())); + sb.append(String.format("getName=%s%n", r.getName())); + sb.append(String.format("size=%d%n", r.getSize())); + sb.append(String.format("startTime=%d%n", r.getStartTime())); + sb.append(String.format("state=%s%n", r.getState())); + sb.append(String.format("stopTime=%d%n", r.getStopTime())); + return sb.toString(); + } + + public static String asString(Recording r) { + StringBuffer sb = new StringBuffer(); + sb.append(String.format("Recording:%n")); + sb.append(String.format("destination=%s%n", r.getDestination())); + sb.append(String.format("dumpOnExit=%b%n", r.getDumpOnExit())); + sb.append(String.format("duration=%d%n", r.getDuration().getSeconds())); + sb.append(String.format("id=%d%n", r.getId())); + sb.append(String.format("maxAge=%d%n", r.getMaxAge().getSeconds())); + sb.append(String.format("maxSize=%d%n", r.getMaxSize())); + sb.append(String.format("getName=%s%n", r.getName())); + sb.append(String.format("size=%d%n", r.getSize())); + sb.append(String.format("startTime=%d%n", toEpochMillis(r.getStartTime()))); + sb.append(String.format("state=%s%n", r.getState())); + sb.append(String.format("stopTime=%d%n", toEpochMillis(r.getStopTime()))); + return sb.toString(); + } + + public static void verifyMapEquals(Map a, Map b) { + try { + Asserts.assertEquals(a.size(), b.size(), "Wrong number of keys"); + for (String key : a.keySet()) { + Asserts.assertTrue(a.containsKey(key), "Missing key " + key); + Asserts.assertEquals(a.get(key), b.get(key), "Wrong values for key " + key); + //System.out.printf("equal: %s=%s%n", key, a.get(key)); + } + } catch (Exception e) { + System.out.println("Error: " + e.getMessage()); + logMap("a", a); + logMap("b", b); + throw e; + } + } + + public static void logMap(String name, Map map) { + for (String key : map.keySet()) { + System.out.printf("map %s: %s=%s%n", name, key, map.get(key)); + } + } + + private static long toEpochMillis(Instant instant) { + return instant != null ? instant.toEpochMilli() : 0; + } + + public static void verifyEventSettingsEqual(EventType javaType, EventTypeInfo jmxType) { + Map javaSettings = new HashMap<>(); + for (SettingDescriptor settingDescriptor : javaType.getSettingDescriptors()) { + javaSettings.put(settingDescriptor.getName(), settingDescriptor); + } + Asserts.assertFalse(javaSettings.isEmpty(), "No ValueDescriptor for EventType " + javaType.getName()); + + for (SettingDescriptorInfo jmxSetting : jmxType.getSettingDescriptors()) { + final String name = jmxSetting.getName(); + System.out.printf("SettingDescriptorInfo: %s#%s=%s%n", jmxType.getName(), name, jmxSetting.getDefaultValue()); + SettingDescriptor javaSetting = javaSettings.remove(name); + Asserts.assertNotNull(javaSetting, "No Setting for name " + name); + Asserts.assertEquals(jmxSetting.getDefaultValue(), Events.getSetting(javaType, name).getDefaultValue(), "Wrong default value"); + Asserts.assertEquals(jmxSetting.getDescription(), javaSetting.getDescription(), "Wrong description"); + Asserts.assertEquals(jmxSetting.getLabel(), javaSetting.getLabel(), "Wrong label"); + Asserts.assertEquals(jmxSetting.getName(), javaSetting.getName(), "Wrong name"); + Asserts.assertEquals(jmxSetting.getTypeName(), javaSetting.getTypeName(), "Wrong type name"); + Asserts.assertEquals(jmxSetting.getContentType(), javaSetting.getContentType()); + } + + // Verify that all Settings have been matched. + if (!javaSettings.isEmpty()) { + for (String name : javaSettings.keySet()) { + System.out.println("Missing setting" + name + " in EventTypeInfo for " + javaType.getName()); + } + System.out.println(); + System.out.println(javaType.getName() + " Java API"); + System.out.println("==============="); + for (SettingDescriptor v : javaType.getSettingDescriptors()) { + System.out.println(" - " + v.getName()); + } + System.out.println(); + System.out.println(jmxType.getName() + " JMX API"); + System.out.println("==============="); + for (SettingDescriptorInfo v : jmxType.getSettingDescriptors()) { + System.out.println(" - " + v.getName()); + } + + Asserts.fail("Missing setting"); + } + } + + + public static FlightRecorderMXBean getFlighteRecorderMXBean() { + return ManagementFactory.getPlatformMXBean(FlightRecorderMXBean.class); + } + +}