ValidateOpenTypes.java revision 14415:21b1b5d178ff
1/* 2 * Copyright (c) 2004, 2016, 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 24/* 25 * @test 26 * @bug 5024531 27 * @summary Validate open types mapped for the MXBeans in the platform 28 * MBeanServer. 29 * @author Mandy Chung 30 * 31 * @modules jdk.management 32 * @compile ValidateOpenTypes.java 33 * @run main/othervm -verbose:gc ValidateOpenTypes 34 */ 35import java.lang.management.*; 36import javax.management.*; 37import javax.management.openmbean.CompositeData; 38import javax.management.openmbean.TabularData; 39import static java.lang.management.ManagementFactory.*; 40import java.util.List; 41import java.util.Map; 42import com.sun.management.GcInfo; 43 44public class ValidateOpenTypes { 45 private static MBeanServer server = 46 ManagementFactory.getPlatformMBeanServer(); 47 private static ObjectName memory; 48 private static ObjectName thread; 49 private static ObjectName runtime; 50 private static ObjectName os; 51 private static ObjectName heapPool = null; 52 private static ObjectName nonHeapPool = null; 53 54 public static void main(String[] argv) throws Exception { 55 memory = new ObjectName(MEMORY_MXBEAN_NAME); 56 runtime = new ObjectName(RUNTIME_MXBEAN_NAME); 57 thread = new ObjectName(THREAD_MXBEAN_NAME); 58 os = new ObjectName(OPERATING_SYSTEM_MXBEAN_NAME); 59 60 List<MemoryPoolMXBean> pools = getMemoryPoolMXBeans(); 61 for (MemoryPoolMXBean p : pools) { 62 if (heapPool == null && 63 p.getType() == MemoryType.HEAP && 64 p.isUsageThresholdSupported() && 65 p.isCollectionUsageThresholdSupported()) { 66 heapPool = new ObjectName(MEMORY_POOL_MXBEAN_DOMAIN_TYPE + 67 ",name=" + p.getName()); 68 } 69 if (nonHeapPool == null && 70 p.getType() == MemoryType.NON_HEAP && 71 p.isUsageThresholdSupported()) { 72 nonHeapPool = new ObjectName(MEMORY_POOL_MXBEAN_DOMAIN_TYPE + 73 ",name=" + p.getName()); 74 } 75 } 76 77 // Check notification emitters 78 MyListener listener = new MyListener(); 79 server.addNotificationListener(memory, listener, null, null); 80 server.removeNotificationListener(memory, listener); 81 82 checkEnum(); 83 checkList(); 84 checkMap(); 85 checkMemoryUsage(); 86 checkThreadInfo(); 87 88 checkOS(); 89 checkSunGC(); 90 91 System.out.println("Test passed."); 92 } 93 94 private static void checkEnum() throws Exception { 95 String type = (String) server.getAttribute(heapPool, "Type"); 96 if (!type.equals("HEAP")) { 97 throw new RuntimeException("TEST FAILED: " + 98 " incorrect memory type for " + heapPool); 99 } 100 101 type = (String) server.getAttribute(nonHeapPool, "Type"); 102 if (!type.equals("NON_HEAP")) { 103 throw new RuntimeException("TEST FAILED: " + 104 " incorrect memory type for " + nonHeapPool); 105 } 106 } 107 108 private static final String OPTION = "-verbose:gc"; 109 private static void checkList() throws Exception { 110 String[] args = (String[]) server.getAttribute(runtime, 111 "InputArguments"); 112 if (args.length < 1) { 113 throw new RuntimeException("TEST FAILED: " + 114 " empty input arguments"); 115 } 116 // check if -verbose:gc exists 117 boolean found = false; 118 for (String option : args) { 119 if (option.equals(OPTION)) { 120 found = true; 121 break; 122 } 123 } 124 if (!found) { 125 throw new RuntimeException("TEST FAILED: " + 126 "VM option " + OPTION + " not found"); 127 } 128 } 129 130 private static final String KEY1 = "test.property.key1"; 131 private static final String VALUE1 = "test.property.value1"; 132 private static final String KEY2 = "test.property.key2"; 133 private static final String VALUE2 = "test.property.value2"; 134 private static final String KEY3 = "test.property.key3"; 135 private static void checkMap() throws Exception { 136 // Add new system properties 137 System.setProperty(KEY1, VALUE1); 138 System.setProperty(KEY2, VALUE2); 139 140 TabularData props1 = (TabularData) 141 server.getAttribute(runtime, "SystemProperties"); 142 143 String value1 = getProperty(props1, KEY1); 144 if (value1 == null || !value1.equals(VALUE1)) { 145 throw new RuntimeException("TEST FAILED: " + 146 KEY1 + " property found" + 147 " with value = " + value1 + 148 " but expected to be " + VALUE1); 149 } 150 151 String value2 = getProperty(props1, KEY2); 152 if (value2 == null || !value2.equals(VALUE2)) { 153 throw new RuntimeException("TEST FAILED: " + 154 KEY2 + " property found" + 155 " with value = " + value2 + 156 " but expected to be " + VALUE2); 157 } 158 159 String value3 = getProperty(props1, KEY3); 160 if (value3 != null) { 161 throw new RuntimeException("TEST FAILED: " + 162 KEY3 + " property found" + 163 " but should not exist" ); 164 } 165 } 166 private static String getProperty(TabularData td, String propName) { 167 CompositeData cd = td.get(new Object[] { propName}); 168 if (cd != null) { 169 String key = (String) cd.get("key"); 170 if (!propName.equals(key)) { 171 throw new RuntimeException("TEST FAILED: " + 172 key + " property found" + 173 " but expected to be " + propName); 174 } 175 return (String) cd.get("value"); 176 } 177 return null; 178 } 179 180 private static void checkMemoryUsage() throws Exception { 181 // sanity check to have non-negative usage 182 Object u1 = server.getAttribute(memory, "HeapMemoryUsage"); 183 Object u2 = server.getAttribute(memory, "NonHeapMemoryUsage"); 184 Object u3 = server.getAttribute(heapPool, "Usage"); 185 Object u4 = server.getAttribute(nonHeapPool, "Usage"); 186 if (getCommitted(u1) < 0 || 187 getCommitted(u2) < 0 || 188 getCommitted(u3) < 0 || 189 getCommitted(u4) < 0) { 190 throw new RuntimeException("TEST FAILED: " + 191 " expected non-negative committed usage"); 192 } 193 server.invoke(memory, "gc", new Object[0], new String[0]); 194 Object u5 = server.getAttribute(heapPool, "CollectionUsage"); 195 if (getCommitted(u5) < 0) { 196 throw new RuntimeException("TEST FAILED: " + 197 " expected non-negative committed collected usage"); 198 } 199 } 200 201 private static long getCommitted(Object data) { 202 MemoryUsage u = MemoryUsage.from((CompositeData) data); 203 return u.getCommitted(); 204 } 205 206 private static void checkThreadInfo() throws Exception { 207 // assume all threads stay alive 208 long[] ids = (long[]) server.getAttribute(thread, "AllThreadIds"); 209 Object result = server.invoke(thread, 210 "getThreadInfo", 211 new Object[] { ids }, 212 new String[] { "[J" }); 213 for (CompositeData cd : (CompositeData[]) result) { 214 printThreadInfo(cd); 215 } 216 217 result = server.invoke(thread, 218 "getThreadInfo", 219 new Object[] { ids, new Integer(2) }, 220 new String[] { "[J", "int" }); 221 for (CompositeData cd : (CompositeData[]) result) { 222 printThreadInfo(cd); 223 } 224 225 long id = Thread.currentThread().getId(); 226 result = server.invoke(thread, 227 "getThreadInfo", 228 new Object[] { new Long(id) }, 229 new String[] { "long" }); 230 printThreadInfo((CompositeData) result); 231 232 result = server.invoke(thread, 233 "getThreadInfo", 234 new Object[] { new Long(id), new Integer(2) }, 235 new String[] { "long", "int" }); 236 printThreadInfo((CompositeData) result); 237 } 238 239 private static void printThreadInfo(CompositeData cd) { 240 ThreadInfo info = ThreadInfo.from(cd); 241 if (info == null) { 242 throw new RuntimeException("TEST FAILED: " + 243 " Null ThreadInfo"); 244 } 245 246 System.out.print(info.getThreadName()); 247 System.out.print(" id=" + info.getThreadId()); 248 System.out.println(" " + info.getThreadState()); 249 250 for (StackTraceElement s : info.getStackTrace()) { 251 System.out.println(s); 252 } 253 } 254 255 private static void checkOS() throws Exception { 256 Integer cpus = (Integer) server.getAttribute(os, "AvailableProcessors"); 257 System.out.println("# CPUs = " + cpus); 258 Long vmem = (Long) server.getAttribute(os, "CommittedVirtualMemorySize"); 259 System.out.println("Committed virtual memory = " + vmem); 260 } 261 262 private static void checkSunGC() throws Exception { 263 // Test com.sun.management proxy 264 List<GarbageCollectorMXBean> gcs = getGarbageCollectorMXBeans(); 265 for (GarbageCollectorMXBean gc : gcs) { 266 ObjectName sunGc = 267 new ObjectName(GARBAGE_COLLECTOR_MXBEAN_DOMAIN_TYPE + 268 ",name=" + gc.getName()); 269 CompositeData cd = (CompositeData) server.getAttribute(sunGc, "LastGcInfo"); 270 if (cd != null) { 271 System.out.println("GC statistic for : " + gc.getName()); 272 printGcInfo(cd); 273 } 274 } 275 } 276 277 private static void printGcInfo(CompositeData cd) throws Exception { 278 GcInfo info = GcInfo.from(cd); 279 System.out.print("GC #" + info.getId()); 280 System.out.print(" start:" + info.getStartTime()); 281 System.out.print(" end:" + info.getEndTime()); 282 System.out.println(" (" + info.getDuration() + "ms)"); 283 Map<String,MemoryUsage> usage = info.getMemoryUsageBeforeGc(); 284 285 for (Map.Entry<String,MemoryUsage> entry : usage.entrySet()) { 286 String poolname = entry.getKey(); 287 MemoryUsage busage = entry.getValue(); 288 MemoryUsage ausage = info.getMemoryUsageAfterGc().get(poolname); 289 if (ausage == null) { 290 throw new RuntimeException("After Gc Memory does not exist" + 291 " for " + poolname); 292 } 293 System.out.println("Usage for pool " + poolname); 294 System.out.println(" Before GC: " + busage); 295 System.out.println(" After GC: " + ausage); 296 } 297 } 298 299 static class MyListener implements NotificationListener { 300 public void handleNotification(Notification notif, Object handback) { 301 return; 302 } 303 } 304} 305