|
1 /* |
|
2 * Copyright (c) 2015, 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 import org.testng.annotations.Test; |
|
25 import org.testng.Assert; |
|
26 |
|
27 import com.oracle.java.testlibrary.OutputAnalyzer; |
|
28 |
|
29 import com.oracle.java.testlibrary.dcmd.CommandExecutor; |
|
30 import com.oracle.java.testlibrary.dcmd.JMXExecutor; |
|
31 |
|
32 import java.util.concurrent.BrokenBarrierException; |
|
33 import java.util.concurrent.CyclicBarrier; |
|
34 import java.util.concurrent.locks.ReentrantLock; |
|
35 import java.util.regex.Pattern; |
|
36 |
|
37 /* |
|
38 * @test |
|
39 * @summary Test of diagnostic command Thread.print |
|
40 * @library /testlibrary |
|
41 * @build com.oracle.java.testlibrary.* |
|
42 * @build com.oracle.java.testlibrary.dcmd.* |
|
43 * @run testng PrintTest |
|
44 */ |
|
45 public class PrintTest { |
|
46 protected boolean jucLocks = false; |
|
47 |
|
48 CyclicBarrier readyBarrier = new CyclicBarrier(3); |
|
49 CyclicBarrier doneBarrier = new CyclicBarrier(3); |
|
50 |
|
51 private void waitForBarrier(CyclicBarrier b) { |
|
52 try { |
|
53 b.await(); |
|
54 } catch (InterruptedException | BrokenBarrierException e) { |
|
55 Assert.fail("Test error: Caught unexpected exception:", e); |
|
56 } |
|
57 } |
|
58 |
|
59 class MonitorThread extends Thread { |
|
60 Object lock = new Object(); |
|
61 |
|
62 public void run() { |
|
63 /* Hold lock on "lock" to show up in thread dump */ |
|
64 synchronized (lock) { |
|
65 /* Signal that we're ready for thread dump */ |
|
66 waitForBarrier(readyBarrier); |
|
67 |
|
68 /* Released when the thread dump has been taken */ |
|
69 waitForBarrier(doneBarrier); |
|
70 } |
|
71 } |
|
72 } |
|
73 |
|
74 class LockThread extends Thread { |
|
75 ReentrantLock lock = new ReentrantLock(); |
|
76 |
|
77 public void run() { |
|
78 /* Hold lock "lock" to show up in thread dump */ |
|
79 lock.lock(); |
|
80 |
|
81 /* Signal that we're ready for thread dump */ |
|
82 waitForBarrier(readyBarrier); |
|
83 |
|
84 /* Released when the thread dump has been taken */ |
|
85 waitForBarrier(doneBarrier); |
|
86 |
|
87 lock.unlock(); |
|
88 } |
|
89 } |
|
90 |
|
91 public void run(CommandExecutor executor) { |
|
92 MonitorThread mThread = new MonitorThread(); |
|
93 mThread.start(); |
|
94 LockThread lThread = new LockThread(); |
|
95 lThread.start(); |
|
96 |
|
97 /* Wait for threads to get ready */ |
|
98 waitForBarrier(readyBarrier); |
|
99 |
|
100 /* Execute */ |
|
101 OutputAnalyzer output = executor.execute("Thread.print" + (jucLocks ? " -l=true" : "")); |
|
102 |
|
103 /* Signal that we've got the thread dump */ |
|
104 waitForBarrier(doneBarrier); |
|
105 |
|
106 /* |
|
107 * Example output (trimmed) with arrows indicating the rows we are looking for: |
|
108 * |
|
109 * ... |
|
110 * "Thread-2" #24 prio=5 os_prio=0 tid=0x00007f913411f800 nid=0x4fc9 waiting on condition [0x00007f91fbffe000] |
|
111 * java.lang.Thread.State: WAITING (parking) |
|
112 * at sun.misc.Unsafe.park(Native Method) |
|
113 * - parking to wait for <0x000000071a0868a8> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject) |
|
114 * at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175) |
|
115 * at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039) |
|
116 * at java.util.concurrent.CyclicBarrier.dowait(CyclicBarrier.java:234) |
|
117 * at java.util.concurrent.CyclicBarrier.await(CyclicBarrier.java:362) |
|
118 * at Print.waitForBarrier(Print.java:26) |
|
119 * at Print.access$000(Print.java:18) |
|
120 * at Print$LockThread.run(Print.java:58) |
|
121 * |
|
122 * --> Locked ownable synchronizers: |
|
123 * --> - <0x000000071a294930> (a java.util.concurrent.locks.ReentrantLock$NonfairSync) |
|
124 * |
|
125 * "Thread-1" #23 prio=5 os_prio=0 tid=0x00007f913411e800 nid=0x4fc8 waiting on condition [0x00007f9200113000] |
|
126 * java.lang.Thread.State: WAITING (parking) |
|
127 * at sun.misc.Unsafe.park(Native Method) |
|
128 * - parking to wait for <0x000000071a0868a8> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject) |
|
129 * at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175) |
|
130 * at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039) |
|
131 * at java.util.concurrent.CyclicBarrier.dowait(CyclicBarrier.java:234) |
|
132 * at java.util.concurrent.CyclicBarrier.await(CyclicBarrier.java:362) |
|
133 * at Print.waitForBarrier(Print.java:26) |
|
134 * at Print.access$000(Print.java:18) |
|
135 * at Print$MonitorThread.run(Print.java:42) |
|
136 * --> - locked <0x000000071a294390> (a java.lang.Object) |
|
137 * |
|
138 * Locked ownable synchronizers: |
|
139 * - None |
|
140 * |
|
141 * "MainThread" #22 prio=5 os_prio=0 tid=0x00007f923015b000 nid=0x4fc7 in Object.wait() [0x00007f9200840000] |
|
142 * java.lang.Thread.State: WAITING (on object monitor) |
|
143 * at java.lang.Object.wait(Native Method) |
|
144 * - waiting on <0x000000071a70ad98> (a java.lang.UNIXProcess) |
|
145 * at java.lang.Object.wait(Object.java:502) |
|
146 * at java.lang.UNIXProcess.waitFor(UNIXProcess.java:397) |
|
147 * - locked <0x000000071a70ad98> (a java.lang.UNIXProcess) |
|
148 * at com.oracle.java.testlibrary.dcmd.JcmdExecutor.executeImpl(JcmdExecutor.java:32) |
|
149 * at com.oracle.java.testlibrary.dcmd.CommandExecutor.execute(CommandExecutor.java:24) |
|
150 * --> at Print.run(Print.java:74) |
|
151 * at Print.file(Print.java:112) |
|
152 * ... |
|
153 |
|
154 */ |
|
155 output.shouldMatch(".*at " + Pattern.quote(PrintTest.class.getName()) + "\\.run.*"); |
|
156 output.shouldMatch(".*- locked <0x\\p{XDigit}+> \\(a " + Pattern.quote(mThread.lock.getClass().getName()) + "\\).*"); |
|
157 |
|
158 String jucLockPattern1 = ".*Locked ownable synchronizers:.*"; |
|
159 String jucLockPattern2 = ".*- <0x\\p{XDigit}+> \\(a " + Pattern.quote(lThread.lock.getClass().getName()) + ".*"; |
|
160 |
|
161 if (jucLocks) { |
|
162 output.shouldMatch(jucLockPattern1); |
|
163 output.shouldMatch(jucLockPattern2); |
|
164 } else { |
|
165 output.shouldNotMatch(jucLockPattern1); |
|
166 output.shouldNotMatch(jucLockPattern2); |
|
167 } |
|
168 } |
|
169 |
|
170 @Test |
|
171 public void jmx() { |
|
172 run(new JMXExecutor()); |
|
173 } |
|
174 } |