OldThreadGroupTest.java revision 2333d6b20eed39cfac75edaf9643aaf543251537
1/* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18package libcore.java.lang; 19 20import java.util.Vector; 21import junit.framework.TestCase; 22 23public class OldThreadGroupTest extends TestCase implements Thread.UncaughtExceptionHandler { 24 25 class MyThread extends Thread { 26 public volatile int heartBeat = 0; 27 28 public MyThread(ThreadGroup group, String name) 29 throws SecurityException, IllegalThreadStateException { 30 super(group, name); 31 } 32 33 @Override 34 public void run() { 35 while (true) { 36 heartBeat++; 37 try { 38 Thread.sleep(50); 39 } catch (InterruptedException e) { 40 break; 41 } 42 } 43 } 44 45 public boolean isActivelyRunning() { 46 long MAX_WAIT = 100; 47 return isActivelyRunning(MAX_WAIT); 48 } 49 50 public boolean isActivelyRunning(long maxWait) { 51 int beat = heartBeat; 52 long start = System.currentTimeMillis(); 53 do { 54 Thread.yield(); 55 int beat2 = heartBeat; 56 if (beat != beat2) { 57 return true; 58 } 59 } while (System.currentTimeMillis() - start < maxWait); 60 return false; 61 } 62 63 } 64 65 private ThreadGroup initialThreadGroup = null; 66 67 public void test_activeGroupCount() { 68 ThreadGroup tg = new ThreadGroup("group count"); 69 assertEquals("Incorrect number of groups", 70 0, tg.activeGroupCount()); 71 Thread t1 = new Thread(tg, new Runnable() { 72 public void run() { 73 74 } 75 }); 76 assertEquals("Incorrect number of groups", 77 0, tg.activeGroupCount()); 78 t1.start(); 79 assertEquals("Incorrect number of groups", 80 0, tg.activeGroupCount()); 81 new ThreadGroup(tg, "test group 1"); 82 assertEquals("Incorrect number of groups", 83 1, tg.activeGroupCount()); 84 new ThreadGroup(tg, "test group 2"); 85 assertEquals("Incorrect number of groups", 86 2, tg.activeGroupCount()); 87 } 88 89 @SuppressWarnings("deprecation") 90 public void test_allowThreadSuspensionZ() { 91 ThreadGroup tg = new ThreadGroup("thread suspension"); 92 assertTrue("Thread suspention can not be changed", 93 tg.allowThreadSuspension(false)); 94 assertTrue("Thread suspention can not be changed", 95 tg.allowThreadSuspension(true)); 96 } 97 98 /* 99 * Checks whether the current Thread is in the given list. 100 */ 101 private boolean inListOfThreads(Thread[] threads) { 102 for (int i = 0; i < threads.length; i++) { 103 if (Thread.currentThread() == threads[i]) { 104 return true; 105 } 106 } 107 108 return false; 109 } 110 111 public void test_enumerateLThreadArray() { 112 int numThreads = initialThreadGroup.activeCount(); 113 Thread[] listOfThreads = new Thread[numThreads]; 114 115 int countThread = initialThreadGroup.enumerate(listOfThreads); 116 assertEquals(numThreads, countThread); 117 assertTrue("Current thread must be in enumeration of threads", 118 inListOfThreads(listOfThreads)); 119 } 120 121 public void test_enumerateLThreadArrayLZtest_enumerateLThreadArrayLZ() { 122 int numThreads = initialThreadGroup.activeCount(); 123 Thread[] listOfThreads = new Thread[numThreads]; 124 125 int countThread = initialThreadGroup.enumerate(listOfThreads, false); 126 assertEquals(numThreads, countThread); 127 128 countThread = initialThreadGroup.enumerate(listOfThreads, true); 129 assertEquals(numThreads, countThread); 130 assertTrue("Current thread must be in enumeration of threads", 131 inListOfThreads(listOfThreads)); 132 133 ThreadGroup subGroup = new ThreadGroup(initialThreadGroup, "Test Group 1"); 134 int subThreadsCount = 3; 135 Vector<MyThread> subThreads = populateGroupsWithThreads(subGroup, 136 subThreadsCount); 137 138 countThread = initialThreadGroup.enumerate(listOfThreads, true); 139 assertEquals(numThreads, countThread); 140 assertTrue("Current thread must be in enumeration of threads", 141 inListOfThreads(listOfThreads)); 142 143 for(MyThread thr:subThreads) { 144 thr.start(); 145 } 146 // lets give them some time to start 147 try { 148 Thread.sleep(500); 149 } catch (InterruptedException ie) { 150 fail("Should not be interrupted"); 151 } 152 153 int numThreads2 = initialThreadGroup.activeCount(); 154 listOfThreads = new Thread[numThreads2]; 155 156 assertEquals(numThreads + subThreadsCount, numThreads2); 157 158 countThread = initialThreadGroup.enumerate(listOfThreads, true); 159 assertEquals(numThreads2, countThread); 160 assertTrue("Current thread must be in enumeration of threads", 161 inListOfThreads(listOfThreads)); 162 163 for(MyThread thr:subThreads) { 164 thr.interrupt(); 165 } 166 // lets give them some time to die 167 try { 168 Thread.sleep(500); 169 } catch (InterruptedException ie) { 170 fail("Should not be interrupted"); 171 } 172 173 int numThreads3 = initialThreadGroup.activeCount(); 174 listOfThreads = new Thread[numThreads3]; 175 176 assertEquals(numThreads, numThreads3); 177 178 countThread = initialThreadGroup.enumerate(listOfThreads, false); 179 assertEquals(numThreads3, countThread); 180 assertTrue("Current thread must be in enumeration of threads", 181 inListOfThreads(listOfThreads)); 182 } 183 184 public void test_enumerateLThreadGroupArray() { 185 int numGroupThreads = initialThreadGroup.activeGroupCount(); 186 ThreadGroup[] listOfGroups = new ThreadGroup[numGroupThreads]; 187 188 int countGroupThread = initialThreadGroup.enumerate(listOfGroups); 189 assertEquals(numGroupThreads, countGroupThread); 190 191 ThreadGroup[] listOfGroups1 = new ThreadGroup[numGroupThreads + 1]; 192 countGroupThread = initialThreadGroup.enumerate(listOfGroups1); 193 assertEquals(numGroupThreads, countGroupThread); 194 assertNull(listOfGroups1[listOfGroups1.length - 1]); 195 196 ThreadGroup[] listOfGroups2 = new ThreadGroup[numGroupThreads - 1]; 197 countGroupThread = initialThreadGroup.enumerate(listOfGroups2); 198 assertEquals(numGroupThreads - 1, countGroupThread); 199 200 ThreadGroup thrGroup1 = new ThreadGroup("Test Group 1"); 201 countGroupThread = thrGroup1.enumerate(listOfGroups); 202 assertEquals(0, countGroupThread); 203 } 204 205 public void test_enumerateLThreadGroupArrayLZ() { 206 ThreadGroup thrGroup = new ThreadGroup("Test Group 1"); 207 Vector<MyThread> subThreads = populateGroupsWithThreads(thrGroup, 3); 208 int numGroupThreads = thrGroup.activeGroupCount(); 209 ThreadGroup[] listOfGroups = new ThreadGroup[numGroupThreads]; 210 211 assertEquals(0, thrGroup.enumerate(listOfGroups, true)); 212 assertEquals(0, thrGroup.enumerate(listOfGroups, false)); 213 214 for(MyThread thr:subThreads) { 215 thr.start(); 216 } 217 218 numGroupThreads = thrGroup.activeGroupCount(); 219 listOfGroups = new ThreadGroup[numGroupThreads]; 220 221 assertEquals(0, thrGroup.enumerate(listOfGroups, true)); 222 assertEquals(0, thrGroup.enumerate(listOfGroups, false)); 223 224 ThreadGroup subGroup1 = new ThreadGroup(thrGroup, "Test Group 2"); 225 Vector<MyThread> subThreads1 = populateGroupsWithThreads(subGroup1, 3); 226 numGroupThreads = thrGroup.activeGroupCount(); 227 listOfGroups = new ThreadGroup[numGroupThreads]; 228 229 assertEquals(1, thrGroup.enumerate(listOfGroups, true)); 230 assertEquals(1, thrGroup.enumerate(listOfGroups, false)); 231 232 for(MyThread thr:subThreads1) { 233 thr.start(); 234 } 235 numGroupThreads = thrGroup.activeGroupCount(); 236 listOfGroups = new ThreadGroup[numGroupThreads]; 237 238 assertEquals(1, thrGroup.enumerate(listOfGroups, true)); 239 assertEquals(1, thrGroup.enumerate(listOfGroups, false)); 240 241 for(MyThread thr:subThreads) { 242 thr.interrupt(); 243 } 244 245 ThreadGroup subGroup2 = new ThreadGroup(subGroup1, "Test Group 3"); 246 Vector<MyThread> subThreads2 = populateGroupsWithThreads(subGroup2, 3); 247 numGroupThreads = thrGroup.activeGroupCount(); 248 listOfGroups = new ThreadGroup[numGroupThreads]; 249 250 assertEquals(2, thrGroup.enumerate(listOfGroups, true)); 251 assertEquals(1, thrGroup.enumerate(listOfGroups, false)); 252 } 253 254 /** 255 * @tests java.lang.ThreadGroup#interrupt() 256 */ 257 private static boolean interrupted = false; 258 public void test_interrupt() { 259 260 Thread.setDefaultUncaughtExceptionHandler(this); 261 ThreadGroup tg = new ThreadGroup("interrupt"); 262 Thread t1 = new Thread(tg, new Runnable() { 263 public void run() { 264 try { 265 Thread.sleep(5000); 266 } catch (InterruptedException e) { 267 fail("ok"); 268 } 269 } 270 }); 271 assertFalse("Incorrect state of thread", interrupted); 272 t1.start(); 273 assertFalse("Incorrect state of thread", interrupted); 274 t1.interrupt(); 275 try { 276 t1.join(); 277 } catch (InterruptedException e) { 278 } 279 assertTrue("Incorrect state of thread", interrupted); 280 tg.destroy(); 281 } 282 283 public void test_isDestroyed() { 284 final ThreadGroup originalCurrent = getInitialThreadGroup(); 285 final ThreadGroup testRoot = new ThreadGroup(originalCurrent, 286 "Test group"); 287 assertFalse("Test group is not destroyed yet", 288 testRoot.isDestroyed()); 289 testRoot.destroy(); 290 assertTrue("Test group already destroyed", 291 testRoot.isDestroyed()); 292 } 293 294 @SuppressWarnings("deprecation") 295 public void test_resume() { 296 ThreadGroup group = new ThreadGroup("Foo"); 297 298 Thread thread = launchFiveSecondDummyThread(group); 299 300 try { 301 Thread.sleep(1000); 302 } catch (InterruptedException e) { 303 // Ignore 304 } 305 306 // No-op in Android. Must neither have an effect nor throw an exception. 307 Thread.State state = thread.getState(); 308 group.resume(); 309 assertEquals(state, thread.getState()); 310 } 311 312 private Thread launchFiveSecondDummyThread(ThreadGroup group) { 313 Thread thread = new Thread(group, "Bar") { 314 public void run() { 315 try { 316 Thread.sleep(5000); 317 } catch (InterruptedException e) { 318 // Ignore 319 } 320 } 321 }; 322 323 thread.start(); 324 325 return thread; 326 } 327 328 /* 329 * @see java.lang.Thread.UncaughtExceptionHandler#uncaughtException(java.lang.Thread, java.lang.Throwable) 330 */ 331 public void uncaughtException(Thread t, Throwable e) { 332 interrupted = true; 333 Thread.setDefaultUncaughtExceptionHandler(null); 334 } 335 336 @Override 337 protected void setUp() { 338 initialThreadGroup = Thread.currentThread().getThreadGroup(); 339 ThreadGroup rootThreadGroup = initialThreadGroup; 340 while (rootThreadGroup.getParent() != null) { 341 rootThreadGroup = rootThreadGroup.getParent(); 342 } 343 } 344 345 @Override 346 protected void tearDown() { 347 try { 348 // Give the threads a chance to die. 349 Thread.sleep(50); 350 } catch (InterruptedException e) { 351 } 352 } 353 354 private ThreadGroup getInitialThreadGroup() { 355 return initialThreadGroup; 356 } 357 358 private ThreadGroup[] groups(ThreadGroup parent) { 359 // No API to get the count of immediate children only ? 360 int count = parent.activeGroupCount(); 361 ThreadGroup[] all = new ThreadGroup[count]; 362 parent.enumerate(all, false); 363 // Now we may have nulls in the array, we must find the actual size 364 int actualSize = 0; 365 for (; actualSize < all.length; actualSize++) { 366 if (all[actualSize] == null) { 367 break; 368 } 369 } 370 ThreadGroup[] result; 371 if (actualSize == all.length) { 372 result = all; 373 } else { 374 result = new ThreadGroup[actualSize]; 375 System.arraycopy(all, 0, result, 0, actualSize); 376 } 377 378 return result; 379 380 } 381 382 private Vector<MyThread> populateGroupsWithThreads(final ThreadGroup aGroup, 383 final int threadCount) { 384 Vector<MyThread> result = new Vector<MyThread>(); 385 populateGroupsWithThreads(aGroup, threadCount, result); 386 return result; 387 388 } 389 390 private void populateGroupsWithThreads(final ThreadGroup aGroup, 391 final int threadCount, final Vector<MyThread> allCreated) { 392 for (int i = 0; i < threadCount; i++) { 393 final int iClone = i; 394 final String name = "(MyThread)N =" + iClone + "/" + threadCount 395 + " ,Vector size at creation: " + allCreated.size(); 396 397 MyThread t = new MyThread(aGroup, name); 398 allCreated.addElement(t); 399 } 400 401 // Recursively for subgroups (if any) 402 ThreadGroup[] children = groups(aGroup); 403 for (ThreadGroup element : children) { 404 populateGroupsWithThreads(element, threadCount, allCreated); 405 } 406 407 } 408} 409