ThreadInfoCompositeData.java revision 11484:03df711f2cab
1/*
2 * Copyright (c) 2004, 2005, 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     4982289
27 * @summary Test ThreadInfo.from to return a valid
28 *          ThreadInfo object. Or throw exception if
29 *          the input CompositeData is invalid.
30 * @author  Mandy Chung
31 *
32 * @compile OpenTypeConverter.java
33 * @build ThreadInfoCompositeData
34 * @run main ThreadInfoCompositeData
35 */
36
37import javax.management.openmbean.*;
38import java.lang.management.LockInfo;
39import java.lang.management.MonitorInfo;
40import java.lang.management.ThreadInfo;
41
42public class ThreadInfoCompositeData {
43    private static StackTraceElement[] ste = new StackTraceElement[1];
44    private static CompositeData[] steCD = new CompositeData[1];
45    private static String lockClassName = "myClass";
46    private static int lockIdentityHashCode = 123456;
47    private static String lockName = lockClassName + '@' +
48        Integer.toHexString(lockIdentityHashCode);
49    private static LockInfo lockInfo =
50        new LockInfo(lockClassName, lockIdentityHashCode);
51
52    public static void main(String[] argv) throws Exception {
53        // A valid CompositeData is passed to ThreadInfo
54        createGoodCompositeData();
55        // A valid CompositeData for JDK 5.0 ThreadInfo
56        // is passed to ThreadInfo
57        createV5ThreadInfo();
58        // An invalid CompositeData is passed to ThreadInfo.from()
59        badNameCompositeData();
60        badTypeCompositeData();
61        System.out.println("Test passed");
62    }
63
64    public static void createGoodCompositeData() throws Exception {
65        CompositeType ct =
66            new CompositeType("MyCompositeType",
67                              "CompositeType for ThreadInfo",
68                              validItemNames,
69                              validItemNames,
70                              validItemTypes);
71        CompositeData cd =
72            new CompositeDataSupport(ct,
73                                     validItemNames,
74                                     values);
75        ThreadInfo info = ThreadInfo.from(cd);
76        checkThreadInfo(info);
77   }
78
79    public static void createV5ThreadInfo() throws Exception {
80        String[] v5ItemNames = new String[NUM_V5_ATTS];
81        OpenType[] v5ItemTypes = new OpenType[NUM_V5_ATTS];
82        Object[] v5ItemValues = new Object[NUM_V5_ATTS];
83        for (int i = 0; i < NUM_V5_ATTS; i++) {
84            v5ItemNames[i] = validItemNames[i];
85            v5ItemTypes[i] = validItemTypes[i];
86            v5ItemValues[i] = values[i];
87        }
88        CompositeType ct =
89            new CompositeType("MyCompositeType",
90                              "CompositeType for JDK 5.0 ThreadInfo",
91                              v5ItemNames,
92                              v5ItemNames,
93                              v5ItemTypes);
94        CompositeData cd =
95            new CompositeDataSupport(ct,
96                                     v5ItemNames,
97                                     v5ItemValues);
98        ThreadInfo info = ThreadInfo.from(cd);
99        checkThreadInfo(info);
100   }
101
102   static void checkThreadInfo(ThreadInfo info) throws Exception {
103        if (info.getThreadId() != ((Long) values[THREAD_ID]).longValue()) {
104            throw new RuntimeException("Thread Id = " + info.getThreadId() +
105               " expected = " + values[THREAD_ID]);
106        }
107        if (!info.getThreadName().equals(values[THREAD_NAME])) {
108            throw new RuntimeException("Thread Name = " +
109               info.getThreadName() + " expected = " + values[THREAD_NAME]);
110        }
111        if (info.getThreadState() != Thread.State.RUNNABLE) {
112            throw new RuntimeException("Thread Name = " +
113               info.getThreadName() + " expected = " + Thread.State.RUNNABLE);
114        }
115        if (info.getBlockedTime() != ((Long) values[BLOCKED_TIME]).longValue()) {
116            throw new RuntimeException("blocked time = " +
117               info.getBlockedTime() +
118               " expected = " + values[BLOCKED_TIME]);
119        }
120        if (info.getBlockedCount() != ((Long) values[BLOCKED_COUNT]).longValue()) {
121            throw new RuntimeException("blocked count = " +
122               info.getBlockedCount() +
123               " expected = " + values[BLOCKED_COUNT]);
124        }
125        if (info.getWaitedTime() != ((Long) values[WAITED_TIME]).longValue()) {
126            throw new RuntimeException("waited time = " +
127               info.getWaitedTime() +
128               " expected = " + values[WAITED_TIME]);
129        }
130        if (info.getWaitedCount() != ((Long) values[WAITED_COUNT]).longValue()) {
131            throw new RuntimeException("waited count = " +
132               info.getWaitedCount() +
133               " expected = " + values[WAITED_COUNT]);
134        }
135        if (!info.getLockName().equals(values[LOCK_NAME])) {
136            throw new RuntimeException("Lock Name = " +
137               info.getLockName() + " expected = " + values[LOCK_NAME]);
138        }
139        if (info.getLockOwnerId() !=
140                ((Long) values[LOCK_OWNER_ID]).longValue()) {
141            throw new RuntimeException(
142               "LockOwner Id = " + info.getLockOwnerId() +
143               " expected = " + values[LOCK_OWNER_ID]);
144        }
145        if (!info.getLockOwnerName().equals(values[LOCK_OWNER_NAME])) {
146            throw new RuntimeException("LockOwner Name = " +
147               info.getLockOwnerName() + " expected = " +
148               values[LOCK_OWNER_NAME]);
149        }
150        if (!values[DAEMON].equals(info.isDaemon())) {
151            throw new RuntimeException("Daemon = " +
152               info.isDaemon() + " expected = " +
153               values[DAEMON]);
154        }
155
156        checkStackTrace(info.getStackTrace());
157
158        checkLockInfo(info.getLockInfo());
159    }
160
161    private static void checkStackTrace(StackTraceElement[] s)
162        throws Exception {
163        if (ste.length != s.length) {
164            throw new RuntimeException("Stack Trace length = " +
165                s.length + " expected = " + ste.length);
166        }
167
168        StackTraceElement s1 = ste[0];
169        StackTraceElement s2 = s[0];
170
171        if (!s1.getClassName().equals(s2.getClassName())) {
172            throw new RuntimeException("Class name = " +
173                s2.getClassName() + " expected = " + s1.getClassName());
174        }
175        if (!s1.getMethodName().equals(s2.getMethodName())) {
176            throw new RuntimeException("Method name = " +
177                s2.getMethodName() + " expected = " + s1.getMethodName());
178        }
179        if (!s1.getFileName().equals(s2.getFileName())) {
180            throw new RuntimeException("File name = " +
181                s2.getFileName() + " expected = " + s1.getFileName());
182        }
183        if (s1.getLineNumber() != s2.getLineNumber()) {
184            throw new RuntimeException("Line number = " +
185                s2.getLineNumber() + " expected = " + s1.getLineNumber());
186        }
187    }
188
189    private static void checkLockInfo(LockInfo li)
190        throws Exception {
191        if (!li.getClassName().equals(lockInfo.getClassName())) {
192            throw new RuntimeException("Class Name = " +
193                li.getClassName() + " expected = " + lockInfo.getClassName());
194        }
195        if (li.getIdentityHashCode() != lockInfo.getIdentityHashCode()) {
196            throw new RuntimeException("Class Name = " +
197                li.getIdentityHashCode() + " expected = " +
198                lockInfo.getIdentityHashCode());
199        }
200    }
201
202    public static void badNameCompositeData() throws Exception {
203        CompositeType ct =
204            new CompositeType("MyCompositeType",
205                              "CompositeType for ThreadInfo",
206                              badItemNames,
207                              badItemNames,
208                              validItemTypes);
209        CompositeData cd =
210            new CompositeDataSupport(ct,
211                                     badItemNames,
212                                     values);
213
214        try {
215            ThreadInfo info = ThreadInfo.from(cd);
216        } catch (IllegalArgumentException e) {
217            System.out.println("Expected exception: " +
218                e.getMessage());
219            return;
220        }
221        throw new RuntimeException(
222            "IllegalArgumentException not thrown");
223    }
224
225    public static void badTypeCompositeData() throws Exception {
226        CompositeType ct =
227            new CompositeType("MyCompositeType",
228                              "CompositeType for ThreadInfo",
229                              validItemNames,
230                              validItemNames,
231                              badItemTypes);
232
233        // patch values[STACK_TRACE] to Long
234        values[STACK_TRACE] = new Long(1000);
235        values[LOCK_INFO] = new Long(1000);
236        CompositeData cd =
237            new CompositeDataSupport(ct,
238                                     validItemNames,
239                                     values);
240
241        try {
242            ThreadInfo info = ThreadInfo.from(cd);
243        } catch (IllegalArgumentException e) {
244            System.out.println("Expected exception: " +
245                e.getMessage());
246            return;
247        }
248        throw new RuntimeException(
249            "IllegalArgumentException not thrown");
250    }
251
252    private static final int THREAD_ID       = 0;
253    private static final int THREAD_NAME     = 1;
254    private static final int THREAD_STATE    = 2;
255    private static final int BLOCKED_TIME    = 3;
256    private static final int BLOCKED_COUNT   = 4;
257    private static final int WAITED_TIME     = 5;
258    private static final int WAITED_COUNT    = 6;
259    private static final int LOCK_NAME       = 7;
260    private static final int LOCK_OWNER_ID   = 8;
261    private static final int LOCK_OWNER_NAME = 9;
262    private static final int STACK_TRACE     = 10;
263    private static final int SUSPENDED       = 11;
264    private static final int IN_NATIVE       = 12;
265    private static final int NUM_V5_ATTS     = 13;
266    // JDK 6.0 ThreadInfo attributes
267    private static final int LOCK_INFO       = 13;
268    // JDK 9.0 ThreadInfo attributes
269    private static final int DAEMON          = 14;
270    private static final int PRIORITY        = 15;
271
272    private static final String[] validItemNames = {
273        "threadId",
274        "threadName",
275        "threadState",
276        "blockedTime",
277        "blockedCount",
278        "waitedTime",
279        "waitedCount",
280        "lockName",
281        "lockOwnerId",
282        "lockOwnerName",
283        "stackTrace",
284        "suspended",
285        "inNative",
286        "lockInfo",
287        "daemon",
288        "priority",
289    };
290
291    private static OpenType[] validItemTypes = {
292        SimpleType.LONG,
293        SimpleType.STRING,
294        SimpleType.STRING,
295        SimpleType.LONG,
296        SimpleType.LONG,
297        SimpleType.LONG,
298        SimpleType.LONG,
299        SimpleType.STRING,
300        SimpleType.LONG,
301        SimpleType.STRING,
302        null,  // ArrayType for StackTraceElement[]
303        SimpleType.BOOLEAN,
304        SimpleType.BOOLEAN,
305        null,  // CompositeType for LockInfo
306        SimpleType.BOOLEAN,
307        SimpleType.INTEGER,
308    };
309
310    private static Object[] values = {
311        new Long(100),
312        "FooThread",
313        "RUNNABLE",
314        new Long(200),
315        new Long(10),
316        new Long(300),
317        new Long(20),
318        lockName,
319        new Long(99),
320        "BarThread",
321        steCD,
322        new Boolean(false),
323        new Boolean(false),
324        null, // To be initialized to lockInfoCD
325        new Boolean(false),
326        Thread.NORM_PRIORITY,
327    };
328
329    private static final String[] steItemNames = {
330        "className",
331        "methodName",
332        "fileName",
333        "lineNumber",
334        "nativeMethod",
335    };
336
337    private static final String[] lockInfoItemNames = {
338        "className",
339        "identityHashCode",
340    };
341
342    static {
343        // create stack trace element
344        ste[0] = new StackTraceElement("FooClass", "getFoo", "Foo.java", 100);
345
346        // initialize the ste[0] and values and validItemTypes
347        try {
348            CompositeType steCType = (CompositeType)
349                OpenTypeConverter.toOpenType(StackTraceElement.class);
350            validItemTypes[STACK_TRACE] = new ArrayType(1, steCType);
351
352            final Object[] steValue = {
353                ste[0].getClassName(),
354                ste[0].getMethodName(),
355                ste[0].getFileName(),
356                new Integer(ste[0].getLineNumber()),
357                new Boolean(ste[0].isNativeMethod()),
358            };
359
360            steCD[0] =
361                new CompositeDataSupport(steCType,
362                                         steItemNames,
363                                         steValue);
364
365            CompositeType lockInfoCType = (CompositeType)
366                OpenTypeConverter.toOpenType(LockInfo.class);
367            validItemTypes[LOCK_INFO] = lockInfoCType;
368
369            final Object[] lockInfoValue = {
370                lockInfo.getClassName(),
371                lockInfo.getIdentityHashCode(),
372            };
373
374            values[LOCK_INFO] =
375                new CompositeDataSupport(lockInfoCType,
376                                         lockInfoItemNames,
377                                         lockInfoValue);
378        } catch (Exception e) {
379            throw new RuntimeException(e);
380        }
381    }
382
383    private static final String[] badItemNames = {
384        "threadId",
385        "threadName",
386        "threadState",
387        "blockedTime",
388        "blockedCount",
389        "waitedTime",
390        "waitedCount",
391        "lockName",
392        "lockOwnerId",
393        "lockOwnerName",
394        "BadStackTrace", // bad item name
395        "suspended",
396        "inNative",
397        "lockInfo",
398        "daemon",
399        "priority",
400    };
401    private static final OpenType[] badItemTypes = {
402        SimpleType.LONG,
403        SimpleType.STRING,
404        SimpleType.STRING,
405        SimpleType.LONG,
406        SimpleType.LONG,
407        SimpleType.LONG,
408        SimpleType.LONG,
409        SimpleType.STRING,
410        SimpleType.LONG,
411        SimpleType.STRING,
412        SimpleType.LONG,  // bad type
413        SimpleType.BOOLEAN,
414        SimpleType.BOOLEAN,
415        SimpleType.LONG,  // bad type
416        SimpleType.BOOLEAN,
417        SimpleType.INTEGER,
418    };
419
420}
421