1 /* 2 * Copyright (c) 2013, 2017, 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. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 package org.graalvm.compiler.hotspot.test; 24 25 import static org.junit.Assert.assertEquals; 26 import static org.junit.Assert.assertNotNull; 27 import static org.junit.Assert.assertNotSame; 28 import static org.junit.Assert.assertNull; 29 import static org.junit.Assert.assertSame; 30 import static org.junit.Assert.assertTrue; 31 32 import java.lang.management.ManagementFactory; 33 import java.lang.reflect.Field; 34 35 import java.util.Arrays; 36 import javax.management.Attribute; 37 import javax.management.MBeanAttributeInfo; 38 import javax.management.MBeanInfo; 39 import javax.management.MBeanOperationInfo; 40 import javax.management.MBeanServer; 41 import javax.management.ObjectInstance; 42 import javax.management.ObjectName; 43 44 import org.graalvm.compiler.debug.DebugOptions; 45 import org.graalvm.compiler.hotspot.HotSpotGraalMBean; 46 import org.graalvm.compiler.options.OptionValues; 47 import org.graalvm.compiler.test.GraalTest; 48 import org.graalvm.util.EconomicMap; 49 import org.junit.Assume; 50 import org.junit.Test; 51 52 import jdk.vm.ci.meta.MetaAccessProvider; 53 import jdk.vm.ci.meta.ResolvedJavaMethod; 54 55 public class HotSpotGraalMBeanTest { 56 57 public HotSpotGraalMBeanTest() { 58 // No support for registering Graal MBean yet on JDK9 (GR-4025). We cannot 59 // rely on an exception being thrown when accessing ManagementFactory.platformMBeanServer 60 // via reflection as recent JDK9 changes now allow this and issue a warning instead. 61 Assume.assumeTrue(GraalTest.Java8OrEarlier); 62 } 63 64 @Test 65 public void registration() throws Exception { 66 ObjectName name; 67 68 Field field = null; 69 try { 70 field = stopMBeanServer(); 71 } catch (Exception ex) { 72 if (ex.getClass().getName().equals("java.lang.reflect.InaccessibleObjectException")) { 73 // skip on JDK9 74 return; 75 } 76 } 77 assertNull("The platformMBeanServer isn't initialized now", field.get(null)); 78 79 HotSpotGraalMBean bean = HotSpotGraalMBean.create(null); 80 assertNotNull("Bean created", bean); 81 82 assertNull("It is not registered yet", bean.ensureRegistered(true)); 83 84 MBeanServer server = ManagementFactory.getPlatformMBeanServer(); 85 86 assertNotNull("Now the bean thinks it is registered", name = bean.ensureRegistered(true)); 87 88 assertNotNull("And the bean is found", server.getObjectInstance(name)); 89 } 90 91 private static Field stopMBeanServer() throws NoSuchFieldException, SecurityException, IllegalAccessException, IllegalArgumentException { 92 final Field field = ManagementFactory.class.getDeclaredField("platformMBeanServer"); 93 field.setAccessible(true); 94 field.set(null, null); 95 return field; 96 } 97 98 @Test 99 public void readBeanInfo() throws Exception { 100 ObjectName name; 101 102 assertNotNull("Server is started", ManagementFactory.getPlatformMBeanServer()); 103 104 HotSpotGraalMBean realBean = HotSpotGraalMBean.create(null); 105 assertNotNull("Bean is registered", name = realBean.ensureRegistered(false)); 106 final MBeanServer server = ManagementFactory.getPlatformMBeanServer(); 107 108 ObjectInstance bean = server.getObjectInstance(name); 109 assertNotNull("Bean is registered", bean); 110 MBeanInfo info = server.getMBeanInfo(name); 111 assertNotNull("Info is found", info); 112 113 MBeanAttributeInfo printCompilation = findAttributeInfo("PrintCompilation", info); 114 assertNotNull("PrintCompilation found", printCompilation); 115 assertEquals("true/false", Boolean.class.getName(), printCompilation.getType()); 116 117 Attribute printOn = new Attribute(printCompilation.getName(), Boolean.TRUE); 118 119 Object before = server.getAttribute(name, printCompilation.getName()); 120 server.setAttribute(name, printOn); 121 Object after = server.getAttribute(name, printCompilation.getName()); 122 123 assertNull("Default value was not set", before); 124 assertEquals("Changed to on", Boolean.TRUE, after); 125 } 126 127 private static MBeanAttributeInfo findAttributeInfo(String attrName, MBeanInfo info) { 128 MBeanAttributeInfo printCompilation = null; 129 for (MBeanAttributeInfo attr : info.getAttributes()) { 130 if (attr.getName().equals(attrName)) { 131 assertTrue("Readable", attr.isReadable()); 132 assertTrue("Writable", attr.isWritable()); 133 printCompilation = attr; 134 break; 135 } 136 } 137 return printCompilation; 138 } 139 140 @Test 141 public void optionsAreCached() throws Exception { 142 ObjectName name; 143 144 assertNotNull("Server is started", ManagementFactory.getPlatformMBeanServer()); 145 146 HotSpotGraalMBean realBean = HotSpotGraalMBean.create(null); 147 148 OptionValues original = new OptionValues(EconomicMap.create()); 149 150 assertSame(original, realBean.optionsFor(original, null)); 151 152 assertNotNull("Bean is registered", name = realBean.ensureRegistered(false)); 153 final MBeanServer server = ManagementFactory.getPlatformMBeanServer(); 154 155 ObjectInstance bean = server.getObjectInstance(name); 156 assertNotNull("Bean is registered", bean); 157 MBeanInfo info = server.getMBeanInfo(name); 158 assertNotNull("Info is found", info); 159 160 MBeanAttributeInfo dump = findAttributeInfo("Dump", info); 161 162 Attribute dumpTo1 = new Attribute(dump.getName(), 1); 163 164 server.setAttribute(name, dumpTo1); 165 Object after = server.getAttribute(name, dump.getName()); 166 assertEquals(1, after); 167 168 final OptionValues modified1 = realBean.optionsFor(original, null); 169 assertNotSame(original, modified1); 170 final OptionValues modified2 = realBean.optionsFor(original, null); 171 assertSame("Options are cached", modified1, modified2); 172 173 } 174 175 @Test 176 public void dumpOperation() throws Exception { 177 Field field = null; 178 try { 179 field = stopMBeanServer(); 180 } catch (Exception ex) { 181 if (ex.getClass().getName().equals("java.lang.reflect.InaccessibleObjectException")) { 182 // skip on JDK9 183 return; 184 } 185 } 186 assertNull("The platformMBeanServer isn't initialized now", field.get(null)); 187 188 ObjectName name; 189 190 assertNotNull("Server is started", ManagementFactory.getPlatformMBeanServer()); 191 192 HotSpotGraalMBean realBean = HotSpotGraalMBean.create(null); 193 194 assertNotNull("Bean is registered", name = realBean.ensureRegistered(false)); 195 final MBeanServer server = ManagementFactory.getPlatformMBeanServer(); 196 197 ObjectInstance bean = server.getObjectInstance(name); 198 assertNotNull("Bean is registered", bean); 199 200 MBeanInfo info = server.getMBeanInfo(name); 201 assertNotNull("Info is found", info); 202 203 final MBeanOperationInfo[] arr = info.getOperations(); 204 assertEquals("Currently three overloads", 3, arr.length); 205 MBeanOperationInfo dumpOp = null; 206 for (int i = 0; i < arr.length; i++) { 207 assertEquals("dumpMethod", arr[i].getName()); 208 if (arr[i].getSignature().length == 3) { 209 dumpOp = arr[i]; 210 } 211 } 212 assertNotNull("three args variant found", dumpOp); 213 214 server.invoke(name, "dumpMethod", new Object[]{ 215 "java.util.Arrays", "asList", ":3" 216 }, null); 217 218 MBeanAttributeInfo dump = findAttributeInfo("Dump", info); 219 Attribute dumpTo1 = new Attribute(dump.getName(), ""); 220 server.setAttribute(name, dumpTo1); 221 Object after = server.getAttribute(name, dump.getName()); 222 assertEquals("", after); 223 224 OptionValues empty = new OptionValues(EconomicMap.create()); 225 OptionValues unsetDump = realBean.optionsFor(empty, null); 226 final MetaAccessProvider metaAccess = jdk.vm.ci.runtime.JVMCI.getRuntime().getHostJVMCIBackend().getMetaAccess(); 227 ResolvedJavaMethod method = metaAccess.lookupJavaMethod(Arrays.class.getMethod("asList", Object[].class)); 228 final OptionValues forMethod = realBean.optionsFor(unsetDump, method); 229 assertNotSame(unsetDump, forMethod); 230 Object nothing = unsetDump.getMap().get(DebugOptions.Dump); 231 assertEquals("Empty string", "", nothing); 232 233 Object specialValue = forMethod.getMap().get(DebugOptions.Dump); 234 assertEquals(":3", specialValue); 235 236 OptionValues normalMethod = realBean.optionsFor(unsetDump, null); 237 Object noSpecialValue = normalMethod.getMap().get(DebugOptions.Dump); 238 assertEquals("Empty string", "", noSpecialValue); 239 } 240 241 }