001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one
003: * or more contributor license agreements. See the NOTICE file
004: * distributed with this work for additional information
005: * regarding copyright ownership. The ASF licenses this file
006: * to you under the Apache License, Version 2.0 (the
007: * "License"); you may not use this file except in compliance
008: * with the License. You may obtain a copy of the License at
009: *
010: * http://www.apache.org/licenses/LICENSE-2.0
011: *
012: * Unless required by applicable law or agreed to in writing,
013: * software distributed under the License is distributed on an
014: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015: * KIND, either express or implied. See the License for the
016: * specific language governing permissions and limitations
017: * under the License.
018: *
019: */
020:
021: package org.apache.harmony.lang.management;
022:
023: import java.lang.management.ManagementFactory;
024: import java.util.Hashtable;
025: import java.util.Iterator;
026:
027: import javax.management.Attribute;
028: import javax.management.AttributeList;
029: import javax.management.AttributeNotFoundException;
030: import javax.management.InvalidAttributeValueException;
031: import javax.management.MBeanAttributeInfo;
032: import javax.management.MBeanConstructorInfo;
033: import javax.management.MBeanException;
034: import javax.management.MBeanInfo;
035: import javax.management.MBeanNotificationInfo;
036: import javax.management.MBeanOperationInfo;
037: import javax.management.openmbean.CompositeData;
038:
039: import org.apache.harmony.lang.management.ThreadMXBeanImpl;
040:
041: public class ThreadMXBeanImplTest extends
042: SingleInstanceDynamicMXBeanImplTestBase {
043:
044: protected void setUp() throws Exception {
045: super .setUp();
046: mb = (ThreadMXBeanImpl) ManagementFactory.getThreadMXBean();
047: }
048:
049: protected void tearDown() throws Exception {
050: super .tearDown();
051: }
052:
053: // -----------------------------------------------------------------
054: // DynamicMBean behaviour tests follow ....
055: // -----------------------------------------------------------------
056:
057: public final void testGetAttribute() throws Exception {
058: // The good attributes...
059: assertNotNull(mb.getAttribute("AllThreadIds"));
060: assertTrue(mb.getAttribute("AllThreadIds") instanceof long[]);
061:
062: assertNotNull(mb.getAttribute("DaemonThreadCount"));
063: assertTrue(mb.getAttribute("DaemonThreadCount") instanceof Integer);
064:
065: assertNotNull(mb.getAttribute("PeakThreadCount"));
066: assertTrue(mb.getAttribute("PeakThreadCount") instanceof Integer);
067:
068: assertNotNull(mb.getAttribute("ThreadCount"));
069: assertTrue(mb.getAttribute("ThreadCount") instanceof Integer);
070:
071: assertNotNull(mb.getAttribute("TotalStartedThreadCount"));
072: assertTrue(mb.getAttribute("TotalStartedThreadCount") instanceof Long);
073:
074: assertNotNull(mb.getAttribute("CurrentThreadCpuTimeSupported"));
075: assertTrue(mb.getAttribute("CurrentThreadCpuTimeSupported") instanceof Boolean);
076:
077: if ((Boolean) mb.getAttribute("CurrentThreadCpuTimeSupported")) {
078: assertNotNull(mb.getAttribute("CurrentThreadCpuTime"));
079: assertTrue(mb.getAttribute("CurrentThreadCpuTime") instanceof Long);
080:
081: assertNotNull(mb.getAttribute("CurrentThreadUserTime"));
082: assertTrue(mb.getAttribute("CurrentThreadUserTime") instanceof Long);
083: } else {
084: try {
085: long t1 = (Long) mb
086: .getAttribute("CurrentThreadCpuTime");
087: fail("Should have thrown MBeanException");
088: } catch (MBeanException ignore) {
089: }
090:
091: try {
092: long t2 = (Long) mb
093: .getAttribute("CurrentThreadUserTime");
094: fail("Should have thrown MBeanException");
095: } catch (MBeanException ignore) {
096: }
097: }
098:
099: assertNotNull(mb
100: .getAttribute("ThreadContentionMonitoringSupported"));
101: assertTrue((mb
102: .getAttribute("ThreadContentionMonitoringSupported")) instanceof Boolean);
103:
104: if ((Boolean) mb
105: .getAttribute("ThreadContentionMonitoringSupported")) {
106: assertNotNull(mb
107: .getAttribute("ThreadContentionMonitoringEnabled"));
108: assertTrue(mb
109: .getAttribute("ThreadContentionMonitoringEnabled") instanceof Boolean);
110: } else {
111: try {
112: boolean b = ((Boolean) (mb
113: .getAttribute("ThreadContentionMonitoringEnabled")))
114: .booleanValue();
115: fail("Should have thrown MBeanException");
116: } catch (MBeanException ignore) {
117: }
118: }
119:
120: assertNotNull(mb.getAttribute("ThreadCpuTimeSupported"));
121: assertTrue((mb.getAttribute("ThreadCpuTimeSupported")) instanceof Boolean);
122:
123: if ((Boolean) mb.getAttribute("ThreadCpuTimeSupported")) {
124: assertNotNull(mb.getAttribute("ThreadCpuTimeEnabled"));
125: assertTrue((mb.getAttribute("ThreadCpuTimeEnabled")) instanceof Boolean);
126: } else {
127: try {
128: boolean b = ((Boolean) (mb
129: .getAttribute("ThreadCpuTimeEnabled")))
130: .booleanValue();
131: fail("Should have thrown MBeanException");
132: } catch (MBeanException ignore) {
133: }
134: }
135:
136: // A nonexistent attribute should throw an AttributeNotFoundException
137: try {
138: long rpm = ((Long) (mb.getAttribute("RPM")));
139: fail("Should have thrown an AttributeNotFoundException.");
140: } catch (AttributeNotFoundException ignore) {
141: }
142:
143: // Type mismatch should result in a casting exception
144: try {
145: String bad = (String) (mb
146: .getAttribute("CurrentThreadUserTime"));
147: fail("Should have thrown a ClassCastException");
148: } catch (ClassCastException ignore) {
149: }
150: }
151:
152: public final void testSetAttribute() throws Exception {
153: // There are only two writable attributes in this type.
154:
155: Attribute attr = new Attribute(
156: "ThreadContentionMonitoringEnabled", new Boolean(true));
157:
158: if ((Boolean) mb
159: .getAttribute("ThreadContentionMonitoringSupported")) {
160: mb.setAttribute(attr);
161: } else {
162: try {
163: mb.setAttribute(attr);
164: fail("Should have thrown MBeanException!");
165: } catch (MBeanException ignore) {
166: }
167: }
168:
169: attr = new Attribute("ThreadCpuTimeEnabled", new Boolean(true));
170: if ((Boolean) mb.getAttribute("ThreadCpuTimeSupported")) {
171: mb.setAttribute(attr);
172: } else {
173: try {
174: mb.setAttribute(attr);
175: fail("Should have thrown MBeanException!");
176: } catch (MBeanException ignore) {
177: }
178: }
179:
180: // The rest of the attempted sets should fail
181:
182: attr = new Attribute("AllThreadIds", new long[] { 1L, 2L, 3L,
183: 4L });
184: try {
185: mb.setAttribute(attr);
186: fail("Should have thrown an AttributeNotFoundException.");
187: } catch (AttributeNotFoundException ignore) {
188: }
189:
190: attr = new Attribute("CurrentThreadCpuTime", 1415L);
191: try {
192: mb.setAttribute(attr);
193: fail("Should have thrown an AttributeNotFoundException.");
194: } catch (AttributeNotFoundException ignore) {
195: }
196:
197: attr = new Attribute("DaemonThreadCount", 1415);
198: try {
199: mb.setAttribute(attr);
200: fail("Should have thrown an AttributeNotFoundException.");
201: } catch (AttributeNotFoundException ignore) {
202: }
203:
204: attr = new Attribute("PeakThreadCount", 1415);
205: try {
206: mb.setAttribute(attr);
207: fail("Should have thrown an AttributeNotFoundException.");
208: } catch (AttributeNotFoundException ignore) {
209: }
210:
211: attr = new Attribute("ThreadCount", 1415);
212: try {
213: mb.setAttribute(attr);
214: fail("Should have thrown an AttributeNotFoundException.");
215: } catch (AttributeNotFoundException ignore) {
216: }
217:
218: attr = new Attribute("TotalStartedThreadCount", 1415L);
219: try {
220: mb.setAttribute(attr);
221: fail("Should have thrown an AttributeNotFoundException.");
222: } catch (AttributeNotFoundException ignore) {
223: }
224:
225: attr = new Attribute("CurrentThreadCpuTimeSupported", true);
226: try {
227: mb.setAttribute(attr);
228: fail("Should have thrown an AttributeNotFoundException.");
229: } catch (AttributeNotFoundException ignore) {
230: }
231:
232: attr = new Attribute("ThreadContentionMonitoringEnabled", true);
233:
234: if ((Boolean) mb
235: .getAttribute("ThreadContentionMonitoringSupported")) {
236: mb.setAttribute(attr);
237: } else {
238: try {
239: mb.setAttribute(attr);
240: fail("Should have thrown an AttributeNotFoundException.");
241: } catch (AttributeNotFoundException ignore) {
242: }
243: }
244:
245: attr = new Attribute("ThreadContentionMonitoringSupported",
246: true);
247: try {
248: mb.setAttribute(attr);
249: fail("Should have thrown an AttributeNotFoundException.");
250: } catch (AttributeNotFoundException ignore) {
251: }
252:
253: attr = new Attribute("ThreadCpuTimeEnabled", true);
254: if ((Boolean) mb.getAttribute("ThreadCpuTimeSupported")) {
255: mb.setAttribute(attr);
256: } else {
257: try {
258: mb.setAttribute(attr);
259: fail("Should have thrown an MBeanException.");
260: } catch (MBeanException ignore) {
261: }
262: }
263:
264: attr = new Attribute("ThreadCpuTimeSupported", true);
265: try {
266: mb.setAttribute(attr);
267: fail("Should have thrown an AttributeNotFoundException.");
268: } catch (AttributeNotFoundException ignore) {
269: }
270:
271: // Try and set an attribute with an incorrect type.
272: attr = new Attribute("ThreadContentionMonitoringEnabled",
273: new Long(42));
274: if ((Boolean) mb
275: .getAttribute("ThreadContentionMonitoringSupported")) {
276: try {
277: mb.setAttribute(attr);
278: fail("Should have thrown an InvalidAttributeValueException");
279: } catch (InvalidAttributeValueException ignore) {
280: }
281: }
282: }
283:
284: public final void testGetAttributes() {
285: AttributeList attributes = mb.getAttributes(attribs.keySet()
286: .toArray(new String[] {}));
287: assertNotNull(attributes);
288: assertTrue(attribs.size() >= attributes.size());
289:
290: // Check through the returned values
291: Iterator<?> it = attributes.iterator();
292: while (it.hasNext()) {
293: Attribute element = (Attribute) it.next();
294: assertNotNull(element);
295: String name = element.getName();
296: Object value = element.getValue();
297: if (attribs.containsKey(name)) {
298: if (attribs.get(name).type.equals(Long.TYPE.getName())) {
299: // Values of -1 are permitted for this kind of bean.
300: // e.g. -1 can be returned from
301: // getCurrentThreadCpuTime()
302: // if CPU time measurement is currently disabled.
303: assertTrue(((Long) (value)) > -2);
304: }// end else a long expected
305: else if ((attribs.get(name).type).equals(Boolean.TYPE
306: .getName())) {
307: boolean tmp = ((Boolean) value).booleanValue();
308: }// end else a boolean expected
309: else if (attribs.get(name).type.equals(Integer.TYPE
310: .getName())) {
311: // Values of -1 are permitted for this kind of bean.
312: // e.g. -1 can be returned from
313: // getCurrentThreadCpuTime()
314: // if CPU time measurement is currently disabled.
315: assertTrue(((Integer) (value)) > -2);
316: }// end else a long expected
317: else if (attribs.get(name).type.equals("[J")) {
318: long[] tmp = (long[]) value;
319: assertNotNull(tmp);
320: }// end else a String array expected
321: else {
322: fail("Unexpected attribute type returned! : "
323: + name + " , value = " + value);
324: }
325: }// end if a known attribute
326: else {
327: fail("Unexpected attribute name returned!");
328: }// end else an unknown attribute
329: }// end while
330: }
331:
332: public final void testSetAttributes() {
333: // Ideal scenario...
334: AttributeList attList = new AttributeList();
335: Attribute tcme = new Attribute(
336: "ThreadContentionMonitoringEnabled", new Boolean(false));
337: Attribute tcte = new Attribute("ThreadCpuTimeEnabled",
338: new Boolean(true));
339: attList.add(tcme);
340: attList.add(tcte);
341: AttributeList setAttrs = mb.setAttributes(attList);
342: assertNotNull(setAttrs);
343: assertTrue(setAttrs.size() <= 2);
344:
345: // A failure scenario - a non-existent attribute...
346: AttributeList badList = new AttributeList();
347: Attribute garbage = new Attribute("Auchenback", new Long(2888));
348: badList.add(garbage);
349: setAttrs = mb.setAttributes(badList);
350: assertNotNull(setAttrs);
351: assertTrue(setAttrs.size() == 0);
352:
353: // Another failure scenario - a non-writable attribute...
354: badList = new AttributeList();
355: garbage = new Attribute("ThreadCount", new Long(2888));
356: badList.add(garbage);
357: setAttrs = mb.setAttributes(badList);
358: assertNotNull(setAttrs);
359: assertTrue(setAttrs.size() == 0);
360:
361: // Yet another failure scenario - a wrongly-typed attribute...
362: badList = new AttributeList();
363: garbage = new Attribute("ThreadCpuTimeEnabled", new Long(2888));
364: badList.add(garbage);
365: setAttrs = mb.setAttributes(badList);
366: assertNotNull(setAttrs);
367: assertTrue(setAttrs.size() == 0);
368: }
369:
370: public final void testInvoke() throws Exception {
371: // This type of bean has 8 different operations that can be invoked
372: // on it.
373: Object retVal = mb.invoke("findMonitorDeadlockedThreads",
374: new Object[] {}, null);
375: // Can get a null return if there are currently no deadlocked
376: // threads.
377:
378: // Good case.
379: retVal = mb.invoke("getThreadCpuTime", new Object[] { new Long(
380: Thread.currentThread().getId()) },
381: new String[] { Long.TYPE.getName() });
382: assertNotNull(retVal);
383: assertTrue(retVal instanceof Long);
384:
385: // Force exception by passing in a negative Thread id
386: try {
387: retVal = mb.invoke("getThreadCpuTime",
388: new Object[] { new Long(-757) },
389: new String[] { Long.TYPE.getName() });
390: fail("Should have thrown an IllegalArgumentException!");
391: } catch (IllegalArgumentException ignore) {
392: }
393:
394: // Good case. long
395: retVal = mb.invoke("getThreadInfo", new Object[] { new Long(
396: Thread.currentThread().getId()) },
397: new String[] { Long.TYPE.getName() });
398: assertNotNull(retVal);
399: assertTrue(retVal instanceof CompositeData);
400: CompositeData cd = (CompositeData) retVal;
401: assertTrue(cd.containsKey("threadId"));
402:
403: // Force exception by passing in a negative Thread id. long
404: try {
405: retVal = mb.invoke("getThreadInfo",
406: new Object[] { new Long(-5353) },
407: new String[] { Long.TYPE.getName() });
408: fail("Should have thrown an IllegalArgumentException!");
409: } catch (IllegalArgumentException ignore) {
410: }
411:
412: // Good case. long, int
413: retVal = mb.invoke("getThreadInfo", new Object[] {
414: new Long(Thread.currentThread().getId()),
415: new Integer(0) }, new String[] { Long.TYPE.getName(),
416: Integer.TYPE.getName() });
417: // TODO Can't test until we can get back ThreadInfo objects
418: // from the getThreadInfo(long) method.
419: assertNotNull(retVal);
420: assertTrue(retVal instanceof CompositeData);
421: cd = (CompositeData) retVal;
422: assertTrue(cd.containsKey("threadId"));
423:
424: // Force exception by passing in a negative Thread id. long, int
425: try {
426: retVal = mb.invoke("getThreadInfo", new Object[] {
427: new Long(-8467), new Integer(0) }, new String[] {
428: Long.TYPE.getName(), Integer.TYPE.getName() });
429: fail("Should have thrown an IllegalArgumentException!");
430: } catch (IllegalArgumentException ignore) {
431: }
432:
433: // Good case. long[], int
434: retVal = mb.invoke("getThreadInfo", new Object[] {
435: new long[] { Thread.currentThread().getId() },
436: new Integer(0) }, new String[] { "[J",
437: Integer.TYPE.getName() });
438: // TODO Can't test until we can get back ThreadInfo objects
439: // from the getThreadInfo(long) method.
440: assertNotNull(retVal);
441: assertTrue(retVal instanceof CompositeData[]);
442: CompositeData[] cdArray = (CompositeData[]) retVal;
443: assertTrue(cdArray[0].containsKey("threadId"));
444:
445: // Force exception by passing in a negative Thread id. long[], int
446: try {
447: retVal = mb.invoke("getThreadInfo", new Object[] {
448: new long[] { -54321L }, new Integer(0) },
449: new String[] { "[J", Integer.TYPE.getName() });
450: fail("Should have thrown an IllegalArgumentException!");
451: } catch (IllegalArgumentException ignore) {
452: }
453:
454: // Good case. long[]
455: retVal = mb.invoke("getThreadInfo",
456: new Object[] { new long[] { Thread.currentThread()
457: .getId() } }, new String[] { "[J" });
458: assertNotNull(retVal);
459: assertTrue(retVal instanceof CompositeData[]);
460: cdArray = (CompositeData[]) retVal;
461: assertTrue(cdArray[0].containsKey("threadId"));
462:
463: // Force exception by passing in a negative Thread id. long[]
464: try {
465: retVal = mb.invoke("getThreadInfo",
466: new Object[] { new long[] { -74747L } },
467: new String[] { "[J" });
468: fail("Should have thrown an IllegalArgumentException!");
469: } catch (IllegalArgumentException ignore) {
470: }
471:
472: // Good case.
473: retVal = mb
474: .invoke("getThreadUserTime", new Object[] { new Long(
475: Thread.currentThread().getId()) },
476: new String[] { Long.TYPE.getName() });
477: assertNotNull(retVal);
478: assertTrue(retVal instanceof Long);
479:
480: // Force exception by passing in a negative Thread id
481: try {
482: retVal = mb.invoke("getThreadUserTime",
483: new Object[] { new Long(-757) },
484: new String[] { Long.TYPE.getName() });
485: fail("Should have thrown an IllegalArgumentException!");
486: } catch (IllegalArgumentException ignore) {
487: }
488:
489: retVal = mb.invoke("resetPeakThreadCount", new Object[] {},
490: null);
491: assertNull(retVal);
492: // Verify that after this operation is invoked, the
493: // peak thread count equals the value of current thread count
494: // taken prior to this method call.
495: assertTrue(((Integer) mb.getAttribute("PeakThreadCount"))
496: .equals((Integer) mb.getAttribute("ThreadCount")));
497: }
498:
499: public final void testGetMBeanInfo() {
500: MBeanInfo mbi = mb.getMBeanInfo();
501: assertNotNull(mbi);
502:
503: // Now make sure that what we got back is what we expected.
504:
505: // Class name
506: assertTrue(mbi.getClassName().equals(mb.getClass().getName()));
507:
508: // No public constructors
509: MBeanConstructorInfo[] constructors = mbi.getConstructors();
510: assertNotNull(constructors);
511: assertTrue(constructors.length == 0);
512:
513: // No public operations
514: MBeanOperationInfo[] operations = mbi.getOperations();
515: assertNotNull(operations);
516: assertTrue(operations.length == 8);
517:
518: // No notifications
519: MBeanNotificationInfo[] notifications = mbi.getNotifications();
520: assertNotNull(notifications);
521: assertTrue(notifications.length == 0);
522:
523: // Description is just the class name (until I hear it should be
524: // different)
525: assertTrue(mbi.getDescription().equals(mb.getClass().getName()));
526:
527: // Sixteen attributes - none writable.
528: MBeanAttributeInfo[] attributes = mbi.getAttributes();
529: assertNotNull(attributes);
530: assertTrue(attributes.length == 12);
531: for (int i = 0; i < attributes.length; i++) {
532: MBeanAttributeInfo info = attributes[i];
533: assertNotNull(info);
534: validateAttributeInfo(info);
535: }// end for
536: }
537:
538: @Override
539: protected void populateTestAttributes() {
540: attribs = new Hashtable<String, AttributeData>();
541: attribs.put("AllThreadIds", new AttributeData("[J", true,
542: false, false));
543: attribs.put("CurrentThreadCpuTime", new AttributeData(Long.TYPE
544: .getName(), true, false, false));
545: attribs.put("CurrentThreadUserTime", new AttributeData(
546: Long.TYPE.getName(), true, false, false));
547: attribs.put("DaemonThreadCount", new AttributeData(Integer.TYPE
548: .getName(), true, false, false));
549: attribs.put("PeakThreadCount", new AttributeData(Integer.TYPE
550: .getName(), true, false, false));
551: attribs.put("ThreadCount", new AttributeData(Integer.TYPE
552: .getName(), true, false, false));
553: attribs.put("TotalStartedThreadCount", new AttributeData(
554: Long.TYPE.getName(), true, false, false));
555: attribs.put("CurrentThreadCpuTimeSupported", new AttributeData(
556: Boolean.TYPE.getName(), true, false, true));
557: attribs.put("ThreadContentionMonitoringEnabled",
558: new AttributeData(Boolean.TYPE.getName(), true, true,
559: true));
560: attribs.put("ThreadContentionMonitoringSupported",
561: new AttributeData(Boolean.TYPE.getName(), true, false,
562: true));
563: attribs.put("ThreadCpuTimeEnabled", new AttributeData(
564: Boolean.TYPE.getName(), true, true, true));
565: attribs.put("ThreadCpuTimeSupported", new AttributeData(
566: Boolean.TYPE.getName(), true, false, true));
567: }
568: }
|