J. Duke | 319a3b9 | 2007-12-01 00:00:00 +0000 | [diff] [blame^] | 1 | /* |
| 2 | * Copyright 2004 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, |
| 20 | * CA 95054 USA or visit www.sun.com if you need additional information or |
| 21 | * have any questions. |
| 22 | */ |
| 23 | |
| 24 | /* |
| 25 | * @test |
| 26 | * @bug 5024531 |
| 27 | * @summary Validata open types mapped for the MXBeans in the platform |
| 28 | * MBeanServer. |
| 29 | * @author Mandy Chung |
| 30 | * |
| 31 | * @compile -source 1.5 ValidateOpenTypes.java |
| 32 | * @run main/othervm -verbose:gc ValidateOpenTypes |
| 33 | */ |
| 34 | import java.lang.management.*; |
| 35 | import javax.management.*; |
| 36 | import javax.management.openmbean.CompositeData; |
| 37 | import javax.management.openmbean.TabularData; |
| 38 | import static java.lang.management.ManagementFactory.*; |
| 39 | import java.util.List; |
| 40 | import java.util.Map; |
| 41 | import java.util.Properties; |
| 42 | import com.sun.management.GcInfo; |
| 43 | |
| 44 | public 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-zero 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-zero 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-zero 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 | } |