/* * Copyright (c) 2013, 2017, 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. * * 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 org.graalvm.compiler.hotspot.test; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNotSame; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; import java.lang.management.ManagementFactory; import java.lang.reflect.Field; import java.util.Arrays; import javax.management.Attribute; import javax.management.MBeanAttributeInfo; import javax.management.MBeanInfo; import javax.management.MBeanOperationInfo; import javax.management.MBeanServer; import javax.management.ObjectInstance; import javax.management.ObjectName; import org.graalvm.compiler.debug.GraalDebugConfig; import org.graalvm.compiler.hotspot.HotSpotGraalMBean; import org.graalvm.compiler.options.OptionValues; import org.graalvm.compiler.test.GraalTest; import org.graalvm.util.EconomicMap; import org.junit.Assume; import org.junit.Test; import jdk.vm.ci.meta.MetaAccessProvider; import jdk.vm.ci.meta.ResolvedJavaMethod; public class HotSpotGraalMBeanTest { public HotSpotGraalMBeanTest() { // No support for registering Graal MBean yet on JDK9 (GR-4025). We cannot // rely on an exception being thrown when accessing ManagementFactory.platformMBeanServer // via reflection as recent JDK9 changes now allow this and issue a warning instead. Assume.assumeTrue(GraalTest.Java8OrEarlier); } @Test public void registration() throws Exception { ObjectName name; Field field = null; try { field = stopMBeanServer(); } catch (Exception ex) { if (ex.getClass().getName().equals("java.lang.reflect.InaccessibleObjectException")) { // skip on JDK9 return; } } assertNull("The platformMBeanServer isn't initialized now", field.get(null)); HotSpotGraalMBean bean = HotSpotGraalMBean.create(null); assertNotNull("Bean created", bean); assertNull("It is not registered yet", bean.ensureRegistered(true)); MBeanServer server = ManagementFactory.getPlatformMBeanServer(); assertNotNull("Now the bean thinks it is registered", name = bean.ensureRegistered(true)); assertNotNull("And the bean is found", server.getObjectInstance(name)); } private static Field stopMBeanServer() throws NoSuchFieldException, SecurityException, IllegalAccessException, IllegalArgumentException { final Field field = ManagementFactory.class.getDeclaredField("platformMBeanServer"); field.setAccessible(true); field.set(null, null); return field; } @Test public void readBeanInfo() throws Exception { ObjectName name; assertNotNull("Server is started", ManagementFactory.getPlatformMBeanServer()); HotSpotGraalMBean realBean = HotSpotGraalMBean.create(null); assertNotNull("Bean is registered", name = realBean.ensureRegistered(false)); final MBeanServer server = ManagementFactory.getPlatformMBeanServer(); ObjectInstance bean = server.getObjectInstance(name); assertNotNull("Bean is registered", bean); MBeanInfo info = server.getMBeanInfo(name); assertNotNull("Info is found", info); MBeanAttributeInfo printCompilation = findAttributeInfo("PrintCompilation", info); assertNotNull("PrintCompilation found", printCompilation); assertEquals("true/false", Boolean.class.getName(), printCompilation.getType()); Attribute printOn = new Attribute(printCompilation.getName(), Boolean.TRUE); Object before = server.getAttribute(name, printCompilation.getName()); server.setAttribute(name, printOn); Object after = server.getAttribute(name, printCompilation.getName()); assertNull("Default value was not set", before); assertEquals("Changed to on", Boolean.TRUE, after); } private static MBeanAttributeInfo findAttributeInfo(String attrName, MBeanInfo info) { MBeanAttributeInfo printCompilation = null; for (MBeanAttributeInfo attr : info.getAttributes()) { if (attr.getName().equals(attrName)) { assertTrue("Readable", attr.isReadable()); assertTrue("Writable", attr.isWritable()); printCompilation = attr; break; } } return printCompilation; } @Test public void optionsAreCached() throws Exception { ObjectName name; assertNotNull("Server is started", ManagementFactory.getPlatformMBeanServer()); HotSpotGraalMBean realBean = HotSpotGraalMBean.create(null); OptionValues original = new OptionValues(EconomicMap.create()); assertSame(original, realBean.optionsFor(original, null)); assertNotNull("Bean is registered", name = realBean.ensureRegistered(false)); final MBeanServer server = ManagementFactory.getPlatformMBeanServer(); ObjectInstance bean = server.getObjectInstance(name); assertNotNull("Bean is registered", bean); MBeanInfo info = server.getMBeanInfo(name); assertNotNull("Info is found", info); MBeanAttributeInfo dump = findAttributeInfo("Dump", info); Attribute dumpTo1 = new Attribute(dump.getName(), 1); server.setAttribute(name, dumpTo1); Object after = server.getAttribute(name, dump.getName()); assertEquals(1, after); final OptionValues modified1 = realBean.optionsFor(original, null); assertNotSame(original, modified1); final OptionValues modified2 = realBean.optionsFor(original, null); assertSame("Options are cached", modified1, modified2); } @Test public void dumpOperation() throws Exception { Field field = null; try { field = stopMBeanServer(); } catch (Exception ex) { if (ex.getClass().getName().equals("java.lang.reflect.InaccessibleObjectException")) { // skip on JDK9 return; } } assertNull("The platformMBeanServer isn't initialized now", field.get(null)); ObjectName name; assertNotNull("Server is started", ManagementFactory.getPlatformMBeanServer()); HotSpotGraalMBean realBean = HotSpotGraalMBean.create(null); assertNotNull("Bean is registered", name = realBean.ensureRegistered(false)); final MBeanServer server = ManagementFactory.getPlatformMBeanServer(); ObjectInstance bean = server.getObjectInstance(name); assertNotNull("Bean is registered", bean); MBeanInfo info = server.getMBeanInfo(name); assertNotNull("Info is found", info); final MBeanOperationInfo[] arr = info.getOperations(); assertEquals("Currently three overloads", 3, arr.length); MBeanOperationInfo dumpOp = null; for (int i = 0; i < arr.length; i++) { assertEquals("dumpMethod", arr[i].getName()); if (arr[i].getSignature().length == 3) { dumpOp = arr[i]; } } assertNotNull("three args variant found", dumpOp); server.invoke(name, "dumpMethod", new Object[]{ "java.util.Arrays", "asList", ":3" }, null); MBeanAttributeInfo dump = findAttributeInfo("Dump", info); Attribute dumpTo1 = new Attribute(dump.getName(), ""); server.setAttribute(name, dumpTo1); Object after = server.getAttribute(name, dump.getName()); assertEquals("", after); OptionValues empty = new OptionValues(EconomicMap.create()); OptionValues unsetDump = realBean.optionsFor(empty, null); final MetaAccessProvider metaAccess = jdk.vm.ci.runtime.JVMCI.getRuntime().getHostJVMCIBackend().getMetaAccess(); ResolvedJavaMethod method = metaAccess.lookupJavaMethod(Arrays.class.getMethod("asList", Object[].class)); final OptionValues forMethod = realBean.optionsFor(unsetDump, method); assertNotSame(unsetDump, forMethod); Object nothing = unsetDump.getMap().get(GraalDebugConfig.Options.Dump); assertEquals("Empty string", "", nothing); Object specialValue = forMethod.getMap().get(GraalDebugConfig.Options.Dump); assertEquals(":3", specialValue); OptionValues normalMethod = realBean.optionsFor(unsetDump, null); Object noSpecialValue = normalMethod.getMap().get(GraalDebugConfig.Options.Dump); assertEquals("Empty string", "", noSpecialValue); } }