/* * Copyright (c) 2004, 2016, 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. */ /* * @test * @bug 5024531 * @summary Validate open types mapped for the MXBeans in the platform * MBeanServer. * @author Mandy Chung * * @compile ValidateOpenTypes.java * @run main/othervm -verbose:gc ValidateOpenTypes */ import java.lang.management.*; import javax.management.*; import javax.management.openmbean.CompositeData; import javax.management.openmbean.TabularData; import static java.lang.management.ManagementFactory.*; import java.util.List; import java.util.Map; import com.sun.management.GcInfo; public class ValidateOpenTypes { private static MBeanServer server = ManagementFactory.getPlatformMBeanServer(); private static ObjectName memory; private static ObjectName thread; private static ObjectName runtime; private static ObjectName os; private static ObjectName heapPool = null; private static ObjectName nonHeapPool = null; public static void main(String[] argv) throws Exception { memory = new ObjectName(MEMORY_MXBEAN_NAME); runtime = new ObjectName(RUNTIME_MXBEAN_NAME); thread = new ObjectName(THREAD_MXBEAN_NAME); os = new ObjectName(OPERATING_SYSTEM_MXBEAN_NAME); List pools = getMemoryPoolMXBeans(); for (MemoryPoolMXBean p : pools) { if (heapPool == null && p.getType() == MemoryType.HEAP && p.isUsageThresholdSupported() && p.isCollectionUsageThresholdSupported()) { heapPool = new ObjectName(MEMORY_POOL_MXBEAN_DOMAIN_TYPE + ",name=" + p.getName()); } if (nonHeapPool == null && p.getType() == MemoryType.NON_HEAP && p.isUsageThresholdSupported()) { nonHeapPool = new ObjectName(MEMORY_POOL_MXBEAN_DOMAIN_TYPE + ",name=" + p.getName()); } } // Check notification emitters MyListener listener = new MyListener(); server.addNotificationListener(memory, listener, null, null); server.removeNotificationListener(memory, listener); checkEnum(); checkList(); checkMap(); checkMemoryUsage(); checkThreadInfo(); checkOS(); checkSunGC(); System.out.println("Test passed."); } private static void checkEnum() throws Exception { String type = (String) server.getAttribute(heapPool, "Type"); if (!type.equals("HEAP")) { throw new RuntimeException("TEST FAILED: " + " incorrect memory type for " + heapPool); } type = (String) server.getAttribute(nonHeapPool, "Type"); if (!type.equals("NON_HEAP")) { throw new RuntimeException("TEST FAILED: " + " incorrect memory type for " + nonHeapPool); } } private static final String OPTION = "-verbose:gc"; private static void checkList() throws Exception { String[] args = (String[]) server.getAttribute(runtime, "InputArguments"); if (args.length < 1) { throw new RuntimeException("TEST FAILED: " + " empty input arguments"); } // check if -verbose:gc exists boolean found = false; for (String option : args) { if (option.equals(OPTION)) { found = true; break; } } if (!found) { throw new RuntimeException("TEST FAILED: " + "VM option " + OPTION + " not found"); } } private static final String KEY1 = "test.property.key1"; private static final String VALUE1 = "test.property.value1"; private static final String KEY2 = "test.property.key2"; private static final String VALUE2 = "test.property.value2"; private static final String KEY3 = "test.property.key3"; private static void checkMap() throws Exception { // Add new system properties System.setProperty(KEY1, VALUE1); System.setProperty(KEY2, VALUE2); TabularData props1 = (TabularData) server.getAttribute(runtime, "SystemProperties"); String value1 = getProperty(props1, KEY1); if (value1 == null || !value1.equals(VALUE1)) { throw new RuntimeException("TEST FAILED: " + KEY1 + " property found" + " with value = " + value1 + " but expected to be " + VALUE1); } String value2 = getProperty(props1, KEY2); if (value2 == null || !value2.equals(VALUE2)) { throw new RuntimeException("TEST FAILED: " + KEY2 + " property found" + " with value = " + value2 + " but expected to be " + VALUE2); } String value3 = getProperty(props1, KEY3); if (value3 != null) { throw new RuntimeException("TEST FAILED: " + KEY3 + " property found" + " but should not exist" ); } } private static String getProperty(TabularData td, String propName) { CompositeData cd = td.get(new Object[] { propName}); if (cd != null) { String key = (String) cd.get("key"); if (!propName.equals(key)) { throw new RuntimeException("TEST FAILED: " + key + " property found" + " but expected to be " + propName); } return (String) cd.get("value"); } return null; } private static void checkMemoryUsage() throws Exception { // sanity check to have non-negative usage Object u1 = server.getAttribute(memory, "HeapMemoryUsage"); Object u2 = server.getAttribute(memory, "NonHeapMemoryUsage"); Object u3 = server.getAttribute(heapPool, "Usage"); Object u4 = server.getAttribute(nonHeapPool, "Usage"); if (getCommitted(u1) < 0 || getCommitted(u2) < 0 || getCommitted(u3) < 0 || getCommitted(u4) < 0) { throw new RuntimeException("TEST FAILED: " + " expected non-negative committed usage"); } server.invoke(memory, "gc", new Object[0], new String[0]); Object u5 = server.getAttribute(heapPool, "CollectionUsage"); if (getCommitted(u5) < 0) { throw new RuntimeException("TEST FAILED: " + " expected non-negative committed collected usage"); } } private static long getCommitted(Object data) { MemoryUsage u = MemoryUsage.from((CompositeData) data); return u.getCommitted(); } private static void checkThreadInfo() throws Exception { // assume all threads stay alive long[] ids = (long[]) server.getAttribute(thread, "AllThreadIds"); Object result = server.invoke(thread, "getThreadInfo", new Object[] { ids }, new String[] { "[J" }); for (CompositeData cd : (CompositeData[]) result) { printThreadInfo(cd); } result = server.invoke(thread, "getThreadInfo", new Object[] { ids, new Integer(2) }, new String[] { "[J", "int" }); for (CompositeData cd : (CompositeData[]) result) { printThreadInfo(cd); } long id = Thread.currentThread().getId(); result = server.invoke(thread, "getThreadInfo", new Object[] { new Long(id) }, new String[] { "long" }); printThreadInfo((CompositeData) result); result = server.invoke(thread, "getThreadInfo", new Object[] { new Long(id), new Integer(2) }, new String[] { "long", "int" }); printThreadInfo((CompositeData) result); } private static void printThreadInfo(CompositeData cd) { ThreadInfo info = ThreadInfo.from(cd); if (info == null) { throw new RuntimeException("TEST FAILED: " + " Null ThreadInfo"); } System.out.print(info.getThreadName()); System.out.print(" id=" + info.getThreadId()); System.out.println(" " + info.getThreadState()); for (StackTraceElement s : info.getStackTrace()) { System.out.println(s); } } private static void checkOS() throws Exception { Integer cpus = (Integer) server.getAttribute(os, "AvailableProcessors"); System.out.println("# CPUs = " + cpus); Long vmem = (Long) server.getAttribute(os, "CommittedVirtualMemorySize"); System.out.println("Committed virtual memory = " + vmem); } private static void checkSunGC() throws Exception { // Test com.sun.management proxy List gcs = getGarbageCollectorMXBeans(); for (GarbageCollectorMXBean gc : gcs) { ObjectName sunGc = new ObjectName(GARBAGE_COLLECTOR_MXBEAN_DOMAIN_TYPE + ",name=" + gc.getName()); CompositeData cd = (CompositeData) server.getAttribute(sunGc, "LastGcInfo"); if (cd != null) { System.out.println("GC statistic for : " + gc.getName()); printGcInfo(cd); } } } private static void printGcInfo(CompositeData cd) throws Exception { GcInfo info = GcInfo.from(cd); System.out.print("GC #" + info.getId()); System.out.print(" start:" + info.getStartTime()); System.out.print(" end:" + info.getEndTime()); System.out.println(" (" + info.getDuration() + "ms)"); Map usage = info.getMemoryUsageBeforeGc(); for (Map.Entry entry : usage.entrySet()) { String poolname = entry.getKey(); MemoryUsage busage = entry.getValue(); MemoryUsage ausage = info.getMemoryUsageAfterGc().get(poolname); if (ausage == null) { throw new RuntimeException("After Gc Memory does not exist" + " for " + poolname); } System.out.println("Usage for pool " + poolname); System.out.println(" Before GC: " + busage); System.out.println(" After GC: " + ausage); } } static class MyListener implements NotificationListener { public void handleNotification(Notification notif, Object handback) { return; } } }