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