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