1 /* 2 * Copyright (c) 2016, 2019, 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 26 package jdk.jfr.cmd; 27 28 import java.nio.file.Path; 29 30 import javax.script.ScriptEngine; 31 import javax.script.ScriptEngineManager; 32 33 import jdk.jfr.ValueDescriptor; 34 import jdk.jfr.consumer.RecordedEvent; 35 import jdk.jfr.consumer.RecordedObject; 36 import jdk.jfr.consumer.RecordingFile; 37 import jdk.nashorn.api.scripting.JSObject; 38 import jdk.testlibrary.Asserts; 39 import jdk.testlibrary.OutputAnalyzer; 40 import jdk.testlibrary.jfr.ExecuteHelper; 41 42 /* 43 * @test 44 * @key jfr 45 * @summary Tests print --json 46 * 47 * @library /lib/testlibrary 48 * @modules jdk.scripting.nashorn 49 * jdk.jfr 50 * 51 * @run main/othervm jdk.jfr.cmd.TestPrintJSON 52 */ 53 public class TestPrintJSON { 54 55 public static void main(String... args) throws Exception { 56 57 Path recordingFile = ExecuteHelper.createProfilingRecording().toAbsolutePath(); 58 59 OutputAnalyzer output = ExecuteHelper.run("print", "--json", recordingFile.toString()); 60 String json = output.getStdout(); 61 62 // Parse JSON using Nashorn 63 String statement = "var jsonObject = " + json; 64 ScriptEngineManager factory = new ScriptEngineManager(); 65 ScriptEngine engine = factory.getEngineByName("nashorn"); 66 engine.eval(statement); 67 JSObject o = (JSObject) engine.get("jsonObject"); 68 JSObject recording = (JSObject) o.getMember("recording"); 69 JSObject events = (JSObject) recording.getMember("events"); 70 71 // Verify events are equal 72 try (RecordingFile rf = new RecordingFile(recordingFile)) { 73 for (Object jsonEvent : events.values()) { 74 RecordedEvent recordedEvent = rf.readEvent(); 75 double typeId = recordedEvent.getEventType().getId(); 76 String startTime = recordedEvent.getStartTime().toString(); 77 String duration = recordedEvent.getDuration().toString(); 78 Asserts.assertEquals(typeId, ((Number) ((JSObject) jsonEvent).getMember("typeId")).doubleValue()); 79 Asserts.assertEquals(startTime, ((JSObject) jsonEvent).getMember("startTime")); 80 Asserts.assertEquals(duration, ((JSObject) jsonEvent).getMember("duration")); 81 assertEquals(jsonEvent, recordedEvent); 82 } 83 Asserts.assertFalse(rf.hasMoreEvents(), "Incorrect number of events"); 84 } 85 } 86 87 private static void assertEquals(Object jsonObject, Object jfrObject) throws Exception { 88 // Check object 89 if (jfrObject instanceof RecordedObject) { 90 JSObject values = (JSObject) ((JSObject) jsonObject).getMember("values"); 91 RecordedObject recObject = (RecordedObject) jfrObject; 92 Asserts.assertEquals(values.values().size(), recObject.getFields().size()); 93 for (ValueDescriptor v : recObject.getFields()) { 94 String name = v.getName(); 95 assertEquals(values.getMember(name), recObject.getValue(name)); 96 return; 97 } 98 } 99 // Check array 100 if (jfrObject != null && jfrObject.getClass().isArray()) { 101 Object[] jfrArray = (Object[]) jfrObject; 102 JSObject jsArray = (JSObject) jsonObject; 103 for (int i = 0; i < jfrArray.length; i++) { 104 assertEquals(jsArray.getSlot(i), jfrArray[i]); 105 } 106 return; 107 } 108 String jsonText = String.valueOf(jsonObject); 109 // Double.NaN / Double.Inifinity is not supported by JSON format, 110 // use null 111 if (jfrObject instanceof Double) { 112 double expected = ((Double) jfrObject); 113 if (Double.isInfinite(expected) || Double.isNaN(expected)) { 114 Asserts.assertEquals("null", jsonText); 115 return; 116 } 117 double value = Double.parseDouble(jsonText); 118 Asserts.assertEquals(expected, value); 119 return; 120 } 121 // Float.NaN / Float.Inifinity is not supported by JSON format, 122 // use null 123 if (jfrObject instanceof Float) { 124 float expected = ((Float) jfrObject); 125 if (Float.isInfinite(expected) || Float.isNaN(expected)) { 126 Asserts.assertEquals("null", jsonText); 127 return; 128 } 129 float value = Float.parseFloat(jsonText); 130 Asserts.assertEquals(expected, value); 131 return; 132 } 133 if (jfrObject instanceof Integer) { 134 Integer expected = ((Integer) jfrObject); 135 double value = Double.parseDouble(jsonText); 136 Asserts.assertEquals(expected.doubleValue(), value); 137 return; 138 } 139 if (jfrObject instanceof Long) { 140 Long expected = ((Long) jfrObject); 141 double value = Double.parseDouble(jsonText); 142 Asserts.assertEquals(expected.doubleValue(), value); 143 return; 144 } 145 146 String jfrText = String.valueOf(jfrObject); 147 Asserts.assertEquals(jfrText, jsonText, "Primitive values don't match. JSON = " + jsonText); 148 } 149 }