blob: dcb82d6ed3017be9f03c0af8d4be4c8c4ba3f6ac [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * Copyright 2005-2006 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 6222826 6379712
27 * @summary Test that all monitors will be well started when sharing
28 * a single thread pool.
29 * @author Luis-Miguel Alventosa
30 * @run clean ThreadPoolTest
31 * @run build ThreadPoolTest
32 * @run main/othervm/timeout=300 ThreadPoolTest 1
33 * @run main/othervm/timeout=300 ThreadPoolTest 2
34 * @run main/othervm/timeout=300 ThreadPoolTest 3
35 * @run main/othervm/timeout=300 -Djmx.x.monitor.maximum.pool.size=5 ThreadPoolTest 1
36 * @run main/othervm/timeout=300 -Djmx.x.monitor.maximum.pool.size=5 ThreadPoolTest 2
37 * @run main/othervm/timeout=300 -Djmx.x.monitor.maximum.pool.size=5 ThreadPoolTest 3
38 * @run main/othervm/timeout=300 -Djmx.x.monitor.maximum.pool.size=-5 ThreadPoolTest 1
39 * @run main/othervm/timeout=300 -Djmx.x.monitor.maximum.pool.size=-5 ThreadPoolTest 2
40 * @run main/othervm/timeout=300 -Djmx.x.monitor.maximum.pool.size=-5 ThreadPoolTest 3
41 */
42
43import java.util.concurrent.atomic.AtomicInteger;
44import javax.management.MBeanServer;
45import javax.management.MBeanServerFactory;
46import javax.management.Notification;
47import javax.management.NotificationListener;
48import javax.management.ObjectName;
49import javax.management.monitor.CounterMonitor;
50import javax.management.monitor.GaugeMonitor;
51import javax.management.monitor.Monitor;
52import javax.management.monitor.MonitorNotification;
53import javax.management.monitor.StringMonitor;
54
55public class ThreadPoolTest {
56
57 static int maxPoolSize;
58 static int nTasks;
59 private static Waiter waiter;
60
61 static final long MAX_WAITING_TIME = 10000;
62
63 // MBean class
64 public class ObservedObject implements ObservedObjectMBean {
65 private boolean called = false;
66 public Integer getInteger() {
67 inform("getInteger()");
68 return 0;
69 }
70 public Double getDouble() {
71 inform("getDouble()");
72 return 0.0;
73 }
74 public String getString() {
75 inform("getString()");
76 return "";
77 }
78 private void inform(String prop) {
79 synchronized(waiter) {
80 if (!called) {
81 called = true;
82 waiter.count();
83 }
84 }
85
86 echo(">>> TASK "+prop+" is called.");
87 }
88 }
89
90 // MBean interface
91 public interface ObservedObjectMBean {
92 public Integer getInteger();
93 public Double getDouble();
94 public String getString();
95 }
96
97 /**
98 * Run test
99 */
100 public int runTest(int monitorType) throws Exception {
101
102
103 ObjectName[] mbeanNames = new ObjectName[nTasks];
104 ObservedObject[] monitored = new ObservedObject[nTasks];
105 ObjectName[] monitorNames = new ObjectName[nTasks];
106 Monitor[] monitor = new Monitor[nTasks];
107 String[] attributes = { "Integer", "Double", "String" };
108
109 try {
110 echo(">>> CREATE MBeanServer");
111 MBeanServer server = MBeanServerFactory.newMBeanServer();
112
113 String domain = server.getDefaultDomain();
114
115 for (int i = 0; i < nTasks; i++) {
116 mbeanNames[i] =
117 new ObjectName(":type=ObservedObject,instance=" + (i + 1));
118 monitored[i] = new ObservedObject();
119 echo(">>> CREATE ObservedObject = " + mbeanNames[i].toString());
120 server.registerMBean(monitored[i], mbeanNames[i]);
121 switch (monitorType) {
122 case 1:
123 monitorNames[i] = new ObjectName(":type=CounterMonitor," +
124 "instance=" + (i + 1));
125 monitor[i] = new CounterMonitor();
126 break;
127 case 2:
128 monitorNames[i] = new ObjectName(":type=GaugeMonitor," +
129 "instance=" + (i + 1));
130 monitor[i] = new GaugeMonitor();
131 break;
132 case 3:
133 monitorNames[i] = new ObjectName(":type=StringMonitor," +
134 "instance=" + (i + 1));
135 monitor[i] = new StringMonitor();
136 break;
137 default:
138 echo("Unsupported monitor type");
139 return 1;
140 }
141 echo(">>> CREATE Monitor = " + monitorNames[i].toString());
142 server.registerMBean(monitor[i], monitorNames[i]);
143 monitor[i].addObservedObject(mbeanNames[i]);
144 monitor[i].setObservedAttribute(attributes[monitorType-1]);
145 monitor[i].setGranularityPeriod(50);
146 monitor[i].start();
147 }
148
149 if (!waiter.waiting(MAX_WAITING_TIME)) {
150 echo("Error, not all "+nTasks+" monitor tasks are called after "
151 +MAX_WAITING_TIME);
152 return 1;
153 }
154 } finally {
155 for (int i = 0; i < nTasks; i++)
156 if (monitor[i] != null)
157 monitor[i].stop();
158 }
159
160 echo("All "+nTasks+" monitors are called.");
161 return 0;
162 }
163
164 /*
165 * Print message
166 */
167 private static void echo(String message) {
168 System.out.println(message);
169 }
170
171 /*
172 * Standalone entry point.
173 *
174 * Run the test and report to stdout.
175 */
176 public static void main (String args[]) throws Exception {
177 Integer size = Integer.getInteger("jmx.x.monitor.maximum.pool.size");
178 if (size == null) {
179 maxPoolSize = 10;
180 echo(">>> MAXIMUM POOL SIZE = 10 [default value]");
181 } else {
182 maxPoolSize = size.intValue() < 1 ? 1 : size.intValue();
183 echo(">>> MAXIMUM POOL SIZE = " + maxPoolSize);
184 }
185
186 nTasks = maxPoolSize + 2;
187 waiter = new Waiter(nTasks);
188 ThreadPoolTest test = new ThreadPoolTest();
189
190 int error = test.runTest(Integer.parseInt(args[0]));
191 if (error > 0) {
192 echo(">>> Unhappy Bye, Bye!");
193 throw new IllegalStateException(
194 "Test FAILED: Unexpected Maximum Pool Size Overflow!");
195 } else {
196 echo(">>> Happy Bye, Bye!");
197 }
198 }
199
200 private static class Waiter {
201 public Waiter(int waitedNB) {
202 this.waitedNB = waitedNB;
203 }
204
205 public void count() {
206 synchronized(this) {
207 counted++;
208
209 if (counted == waitedNB) {
210 this.notifyAll();
211 }
212 }
213 }
214
215 public boolean waiting(long timeout) {
216 final long startTime = System.currentTimeMillis();
217 long toWait = timeout;
218
219 synchronized(this) {
220 while(counted < waitedNB && toWait > 0) {
221 try {
222 this.wait(toWait);
223 } catch (InterruptedException ire) {
224 break;
225 }
226
227 toWait = timeout -
228 (System.currentTimeMillis() - startTime);
229 }
230 }
231
232 return counted == waitedNB;
233 }
234
235 private int waitedNB;
236 private int counted = 0;
237 }
238}