0001: /*
0002: * Licensed to the Apache Software Foundation (ASF) under one or more
0003: * contributor license agreements. See the NOTICE file distributed with
0004: * this work for additional information regarding copyright ownership.
0005: * The ASF licenses this file to You under the Apache License, Version 2.0
0006: * (the "License"); you may not use this file except in compliance with
0007: * the License. You may obtain a copy of the License at
0008: *
0009: * http://www.apache.org/licenses/LICENSE-2.0
0010: *
0011: * Unless required by applicable law or agreed to in writing, software
0012: * distributed under the License is distributed on an "AS IS" BASIS,
0013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0014: * See the License for the specific language governing permissions and
0015: * limitations under the License.
0016: */
0017:
0018: /**
0019: * @author Roman S. Bushmanov
0020: * @version $Revision$
0021: */package java.lang;
0022:
0023: import junit.framework.TestCase;
0024: import java.io.*;
0025:
0026: import org.apache.harmony.test.ReversibleSecurityManager;
0027:
0028: public class ThreadGroupTest extends TestCase {
0029:
0030: private static final String INTERRUPTED_MESSAGE = "thread has been unexpectedly interrupted";
0031:
0032: // max time interval to wait for some events in ms
0033: private static final long waitDuration = 3000;
0034:
0035: // waiting time for some event
0036: private static long waitTime = 0;
0037: private boolean expired;
0038: private static PrintStream systemOut = System.out;
0039: private static PrintStream systemErr = System.err;
0040:
0041: class ExceptionHandler implements Thread.UncaughtExceptionHandler {
0042:
0043: public boolean wasCalled = false;
0044:
0045: public void uncaughtException(Thread t, Throwable e) {
0046: wasCalled = true;
0047: }
0048: }
0049:
0050: class ThreadGroupHandler extends ThreadGroup {
0051: boolean handlerWasCalled = false;
0052:
0053: public ThreadGroupHandler(String name) {
0054: super (name);
0055: }
0056:
0057: public ThreadGroupHandler(ThreadGroup g, String name) {
0058: super (g, name);
0059: }
0060:
0061: public void uncaughtException(Thread t, Throwable e) {
0062: handlerWasCalled = true;
0063: }
0064: }
0065:
0066: class TestThread extends Thread {
0067:
0068: volatile boolean enough = false;
0069:
0070: boolean finished = false;
0071:
0072: TestThread(ThreadGroup group, String name) {
0073: super (group, name);
0074: }
0075:
0076: public void run() {
0077: while (!enough) {
0078: try {
0079: Thread.sleep(100);
0080: } catch (InterruptedException e) {
0081: }
0082: }
0083: finished = true;
0084: }
0085: }
0086:
0087: /**
0088: * Sleep for "interval" ms
0089: * @return true if waitTime is up
0090: */
0091: private static boolean doSleep(int interval) {
0092: try {
0093: Thread.sleep(interval);
0094: } catch (InterruptedException e) {
0095: fail("unexpected InterruptedException while sleeping");
0096: }
0097: waitTime -= interval;
0098: return waitTime <= 0;
0099: }
0100:
0101: /**
0102: * ThreadGroup(String)
0103: */
0104: public void testThreadGroupThreadGroupString() {
0105: ThreadGroup group = new ThreadGroup("group");
0106: assertSame("wrong parrent", Thread.currentThread()
0107: .getThreadGroup(), group.getParent());
0108: }
0109:
0110: /**
0111: * Create a ThreadGroup in a destroyed ThreadGroup
0112: */
0113: public void testThreadGroupThreadGroupString_InDestroyedGroup() {
0114: try {
0115: ThreadGroup group = new ThreadGroup("group");
0116: group.destroy();
0117: new ThreadGroup(group, "group1");
0118: fail("Constructor should throw IllegalThreadStateException!");
0119: } catch (IllegalThreadStateException e) {
0120: return;
0121: }
0122: }
0123:
0124: /**
0125: * test ThreadGroup(null)
0126: */
0127: public void testThreadGroupString_Null() {
0128: ThreadGroup group = null;
0129: try {
0130: group = new ThreadGroup(null);
0131: } catch (NullPointerException e) {
0132: fail("Constructor should accept null names!");
0133: }
0134: assertNull(group.getName());
0135: }
0136:
0137: /**
0138: * activeCount() in a new ThreadGroup
0139: */
0140: public void testActiveCount_NoThreads() {
0141: ThreadGroup group = new ThreadGroup("new");
0142: assertEquals(0, group.activeCount());
0143: }
0144:
0145: /**
0146: * activeCount() in a ThreadGroup with an empty subgroup
0147: */
0148: public void testActiveCount_CreateDestroySubgroup() {
0149: ThreadGroup group = new ThreadGroup("group");
0150: ThreadGroup group1 = new ThreadGroup(group, "group1");
0151: assertEquals(1, group.activeGroupCount());
0152: group1.destroy();
0153: assertEquals(0, group.activeGroupCount());
0154: }
0155:
0156: /**
0157: * activeCount() in a ThreadGroup with a few new threads
0158: */
0159: public void testActiveCount_NewThreads() {
0160: ThreadGroup group = new ThreadGroup("new");
0161: new Thread(group, "t1");
0162: new Thread(group, "t2");
0163: new Thread(group, "t3");
0164: assertEquals(0, group.activeCount());
0165: }
0166:
0167: /**
0168: * activeCount() in a ThreadGroup with a few started and
0169: * terminated threads
0170: */
0171: public void testActiveCount_StartedTerminatedThreads() {
0172: ThreadGroup group = new ThreadGroup("new");
0173: ThreadTest.ThreadRunning t1 = new ThreadTest.ThreadRunning(
0174: group, "t1");
0175: ThreadTest.ThreadRunning t2 = new ThreadTest.ThreadRunning(
0176: group, "t2");
0177: ThreadTest.ThreadRunning t3 = new ThreadTest.ThreadRunning(
0178: group, "t3");
0179: t1.start();
0180: t2.start();
0181: t3.start();
0182: doSleep(100);
0183: assertEquals("incorrect number of started threads", 3, group
0184: .activeCount());
0185: t1.stopWork = true;
0186: t2.stopWork = true;
0187: t3.stopWork = true;
0188: try {
0189: t1.join();
0190: t2.join();
0191: t3.join();
0192: } catch (InterruptedException e) {
0193: fail(INTERRUPTED_MESSAGE);
0194: }
0195: assertEquals("there should be no live threads", 0, group
0196: .activeCount());
0197: }
0198:
0199: /**
0200: * activeCount() in a ThreadGroup with a few threads running in a subgroups
0201: */
0202: public void testActiveCount_Subgroup() {
0203: ThreadGroup parent = new ThreadGroup("parent");
0204: ThreadGroup child1 = new ThreadGroup(parent, "child1");
0205: ThreadTest.ThreadRunning t11 = new ThreadTest.ThreadRunning(
0206: parent, "t11");
0207: ThreadTest.ThreadRunning tc11 = new ThreadTest.ThreadRunning(
0208: child1, "tc11");
0209: ThreadTest.ThreadRunning tc12 = new ThreadTest.ThreadRunning(
0210: child1, "tc12");
0211: ThreadGroup gChild1 = new ThreadGroup(child1, "gChild1");
0212: ThreadTest.ThreadRunning tgc11 = new ThreadTest.ThreadRunning(
0213: gChild1, "tgc11");
0214: ThreadTest.ThreadRunning tgc12 = new ThreadTest.ThreadRunning(
0215: gChild1, "tgc12");
0216: ThreadGroup child2 = new ThreadGroup(parent, "child2");
0217: ThreadTest.ThreadRunning tc21 = new ThreadTest.ThreadRunning(
0218: child2, "tc21");
0219: ThreadTest.ThreadRunning tc22 = new ThreadTest.ThreadRunning(
0220: child2, "tc22");
0221: assertEquals("new threads should not be counted", 0, parent
0222: .activeCount());
0223: t11.start();
0224: tc11.start();
0225: tc12.start();
0226: tgc11.start();
0227: tgc12.start();
0228: tc21.start();
0229: tc22.start();
0230: doSleep(100);
0231: assertEquals("incorrect number of active threads", 7, parent
0232: .activeCount());
0233: t11.stopWork = true;
0234: tc11.stopWork = true;
0235: tc12.stopWork = true;
0236: tgc11.stopWork = true;
0237: tgc12.stopWork = true;
0238: tc21.stopWork = true;
0239: tc22.stopWork = true;
0240: try {
0241: t11.join();
0242: tc11.join();
0243: tc12.join();
0244: tgc11.join();
0245: tgc12.join();
0246: tc21.join();
0247: tc22.join();
0248: } catch (InterruptedException e) {
0249: fail(INTERRUPTED_MESSAGE);
0250: }
0251: assertEquals("there should be no live threads", 0, parent
0252: .activeCount());
0253: }
0254:
0255: /**
0256: * Verify activeGroupCount() for a group containing
0257: * a few subgroups
0258: */
0259: public void testActiveGroupCount_Subgroups() {
0260: ThreadGroup tg1 = new ThreadGroup("group 1");
0261: new ThreadGroup(tg1, "group 11");
0262: ThreadGroup tg12 = new ThreadGroup(tg1, "group 12");
0263: new ThreadGroup(tg1, "group 13");
0264: new ThreadGroup(tg12, "group 121");
0265: new ThreadGroup(tg12, "group 122");
0266: ThreadGroup tg123 = new ThreadGroup(tg12, "group 123");
0267: new Thread(tg123, "thread 1231");
0268: new Thread(tg123, "thread 1232");
0269: assertEquals(6, tg1.activeGroupCount());
0270: }
0271:
0272: /**
0273: * Verify activeGroupCount() after destroying a group
0274: * where one of subgroups is not empty
0275: */
0276: public void testActiveGroupCount_DestroyNonEmptySubgroup() {
0277: ThreadGroup tg1 = new ThreadGroup("group 1");
0278: ThreadGroup tg11 = new ThreadGroup(tg1, "group 11");
0279: ThreadGroup tg12 = new ThreadGroup(tg1, "group 12");
0280: ThreadGroup tg13 = new ThreadGroup(tg1, "group 13");
0281: ThreadGroup tg121 = new ThreadGroup(tg12, "group 121");
0282: ThreadGroup tg122 = new ThreadGroup(tg12, "group 122");
0283: ThreadGroup tg123 = new ThreadGroup(tg12, "group 123");
0284: new ThreadTest.ThreadRunning(tg122, "thread 1221").start();
0285: new ThreadTest.ThreadRunning(tg122, "thread 1222").start();
0286: // Non-empty subgroup tg122 should not be destroyed.
0287: // IllegalThreadStateException should be thrown.
0288: // Groups residing on the right from tg123 in the groups tree
0289: // should not be destroyed as well.
0290: try {
0291: tg1.destroy();
0292: fail("IllegalThreadStateException has not been thrown when "
0293: + "destroying non-empty subgroup");
0294: } catch (IllegalThreadStateException e) {
0295: }
0296: assertEquals("wrong group count in tg1", 0, tg1
0297: .activeGroupCount());
0298: assertEquals("wrong group count in tg12", 0, tg12
0299: .activeGroupCount());
0300: assertTrue("tg1 is not destroyed", tg1.isDestroyed());
0301: assertTrue("tg11 is not destroyed", tg11.isDestroyed());
0302: assertTrue("tg12 is not destroyed", tg12.isDestroyed());
0303: assertTrue("tg13 is destroyed", !tg13.isDestroyed());
0304: assertTrue("tg121 is not destroyed", tg121.isDestroyed());
0305: assertTrue("tg122 is destroyed", !tg122.isDestroyed());
0306: assertTrue("tg123 is destroyed", !tg123.isDestroyed());
0307: }
0308:
0309: /**
0310: * Verify the checkAccess() method
0311: */
0312: public void testCheckAccess() {
0313: SecurityManager sm = System.getSecurityManager();
0314: System.setSecurityManager(new ReversibleSecurityManager());
0315: ThreadGroup tg1 = new ThreadGroup("tg1");
0316: try {
0317: tg1.checkAccess();
0318: } finally {
0319: System.setSecurityManager(sm);
0320: }
0321: }
0322:
0323: /**
0324: * Checks the destroy() method for a destroyed thread group.
0325: * IllegalThreadStateException should be thrown.
0326: */
0327: public void testDestroy_Destroyed() {
0328: ThreadGroup tg1 = new ThreadGroup("tg1");
0329: ThreadGroup tg2 = new ThreadGroup(tg1, "tg2");
0330: tg2.setDaemon(true);
0331: TestThread t2 = new TestThread(tg2, "t2");
0332: t2.start();
0333: t2.enough = true;
0334: try {
0335: t2.join();
0336: } catch (InterruptedException e) {
0337: fail(INTERRUPTED_MESSAGE);
0338: }
0339: // tg2 is daemon and should be already destroyed
0340: try {
0341: tg2.destroy();
0342: fail("IllegalThreadStateException should be thrown "
0343: + "when destroying a destroyed thread group");
0344: } catch (IllegalThreadStateException e) {
0345: }
0346: }
0347:
0348: /**
0349: * Checks the destroy() method for a group containing a destroyed subgroup.
0350: * IllegalThreadStateException should not be thrown.
0351: */
0352: public void testDestroy_DestroyedSubgroup() {
0353: ThreadGroup tg1 = new ThreadGroup("tg1");
0354: ThreadGroup tg2 = new ThreadGroup(tg1, "tg2");
0355: tg2.setDaemon(true);
0356: TestThread t2 = new TestThread(tg2, "t2");
0357: t2.start();
0358: t2.enough = true;
0359: try {
0360: t2.join();
0361: } catch (InterruptedException e) {
0362: fail(INTERRUPTED_MESSAGE);
0363: }
0364:
0365: // tg1 should be destroyed because its subgroup tg2 has been destroyed
0366: // silently as a daemon ThreadGroup with no live threads
0367: try {
0368: tg1.destroy();
0369: } catch (IllegalThreadStateException e) {
0370: fail("IllegalThreadStateException has been thrown when destroying"
0371: + " a thread group containing a destroyed subgroup");
0372: }
0373: }
0374:
0375: /**
0376: * Verify destroying a group where one of subgroups is not empty
0377: * but all threads in it have finished.
0378: */
0379: public void testDestroy_FinishedThreads() {
0380: ThreadGroup tg1 = new ThreadGroup("group 1");
0381: ThreadGroup tg11 = new ThreadGroup(tg1, "group 11");
0382: ThreadGroup tg12 = new ThreadGroup(tg1, "group 12");
0383: ThreadGroup tg13 = new ThreadGroup(tg1, "group 13");
0384: ThreadGroup tg121 = new ThreadGroup(tg12, "group 121");
0385: ThreadGroup tg122 = new ThreadGroup(tg12, "group 122");
0386: ThreadGroup tg123 = new ThreadGroup(tg12, "group 123");
0387: ThreadTest.ThreadRunning t1 = new ThreadTest.ThreadRunning(
0388: tg123, "thread 1231");
0389: t1.start();
0390: ThreadTest.ThreadRunning t2 = new ThreadTest.ThreadRunning(
0391: tg123, "thread 1232");
0392: t2.start();
0393: t1.stopWork = true;
0394: t2.stopWork = true;
0395: try {
0396: t1.join();
0397: t2.join();
0398: } catch (InterruptedException e) {
0399: fail(INTERRUPTED_MESSAGE);
0400: }
0401: for (waitTime = waitDuration; t1.isAlive() && t2.isAlive()
0402: && !(expired = doSleep(10));) {
0403: }
0404: if (expired) {
0405: fail("thread have not finished for " + waitDuration + " ms");
0406: }
0407: try {
0408: tg1.destroy();
0409: } catch (IllegalThreadStateException e) {
0410: fail("IllegalThreadStateException should not been thrown "
0411: + "because threads have fnished");
0412: }
0413: assertTrue(tg1.getName() + " has not been destroyed", tg1
0414: .isDestroyed());
0415: assertTrue(tg11.getName() + " has not been destroyed", tg11
0416: .isDestroyed());
0417: assertTrue(tg12.getName() + " has not been destroyed", tg12
0418: .isDestroyed());
0419: assertTrue(tg13.getName() + " has not been destroyed", tg13
0420: .isDestroyed());
0421: assertTrue(tg121.getName() + " has not been destroyed", tg121
0422: .isDestroyed());
0423: assertTrue(tg122.getName() + " has not been destroyed", tg122
0424: .isDestroyed());
0425: assertTrue(tg123.getName() + " has not been destroyed", tg123
0426: .isDestroyed());
0427: assertEquals("tg1 should be empty", 0, tg1.activeGroupCount());
0428: assertEquals("tg12 should be empty", 0, tg12.activeGroupCount());
0429: }
0430:
0431: /**
0432: * Checks the destroy() method for a group with 3 subgroups.
0433: * Verifies the <code>destroyed</code> flag.
0434: */
0435: public void testDestroy_ThreeChildren() {
0436: ThreadGroup groups[] = { new ThreadGroup("tg0"), null, null,
0437: null };
0438: groups[1] = new ThreadGroup(groups[0], "tg1");
0439: groups[2] = new ThreadGroup(groups[0], "tg2");
0440: groups[3] = new ThreadGroup(groups[0], "tg3");
0441: groups[0].destroy();
0442: assertTrue("group[0] has not been destroyed", groups[0]
0443: .isDestroyed());
0444: assertTrue("group[1] has not been destroyed", groups[1]
0445: .isDestroyed());
0446: assertTrue("group[2] has not been destroyed", groups[2]
0447: .isDestroyed());
0448: assertTrue("group[3] has not been destroyed", groups[3]
0449: .isDestroyed());
0450: }
0451:
0452: /**
0453: * Checks the destroy() method for a group with 2 subgroups.
0454: * Verifies the activeGroupCount() value.
0455: */
0456: public void testDestroy_TwoChildren() {
0457: ThreadGroup group = new ThreadGroup("group");
0458: new ThreadGroup(group, "group1");
0459: new ThreadGroup(group, "group2");
0460: assertEquals(2, group.activeGroupCount());
0461: group.destroy();
0462: assertEquals(0, group.activeGroupCount());
0463: }
0464:
0465: /**
0466: * Verify getMaxPriority()
0467: */
0468: public void testGetMaxPriority() {
0469: ThreadGroup tg = new ThreadGroup("tg");
0470: int groupMaxPriority = tg.getMaxPriority();
0471: assertEquals("incorrect priority", Thread.currentThread()
0472: .getThreadGroup().getMaxPriority(), groupMaxPriority);
0473: Thread t = new Thread(tg, "t");
0474: assertTrue("incorect thread's priority",
0475: t.getPriority() <= groupMaxPriority);
0476: }
0477:
0478: /**
0479: * Verify enumerate(Thread[])
0480: */
0481: public void testEnumerateThread() {
0482: ThreadGroup tg = new ThreadGroup("tg");
0483: ThreadGroup tg1 = new ThreadGroup(tg, "tg1");
0484: ThreadGroup tg2 = new ThreadGroup(tg1, "tg2");
0485: ThreadTest.ThreadRunning tArray[] = new ThreadTest.ThreadRunning[9];
0486: for (int i = 0; i < 3; i++) {
0487: tArray[i] = new ThreadTest.ThreadRunning(tg, "ttt");
0488: tArray[i].start();
0489: tArray[i + 3] = new ThreadTest.ThreadRunning(tg1, "ttt");
0490: tArray[i + 3].start();
0491: tArray[i + 6] = new ThreadTest.ThreadRunning(tg2, "ttt");
0492: tArray[i + 6].start();
0493: }
0494: doSleep(50);
0495: // estimate dimension as 9 threads + 1
0496: int estimateLength = 10;
0497: Thread list[];
0498: int count;
0499: while (true) {
0500: list = new Thread[estimateLength];
0501: count = tg.enumerate(list);
0502: if (count == estimateLength) {
0503: estimateLength *= 2;
0504: } else {
0505: break;
0506: }
0507: }
0508: int enumerateCount = 0;
0509: for (int i = 0; i < count; i++) {
0510: if (list[i].toString().indexOf("ttt") > 0) {
0511: enumerateCount++;
0512: }
0513: }
0514: for (int i = 0; i < 9; i++) {
0515: tArray[i].stopWork = true;
0516: }
0517: assertEquals("incorrect number of threads in tg", 9,
0518: enumerateCount);
0519: }
0520:
0521: /**
0522: * Verify enumerate(Thread[], false)
0523: */
0524: public void testEnumerateThreadBoolean_False() {
0525: ThreadGroup tg = new ThreadGroup("tg");
0526: ThreadGroup tg1 = new ThreadGroup(tg, "tg1");
0527: ThreadGroup tg2 = new ThreadGroup(tg1, "tg2");
0528: ThreadTest.ThreadRunning tArray[] = new ThreadTest.ThreadRunning[9];
0529: for (int i = 0; i < 3; i++) {
0530: tArray[i] = new ThreadTest.ThreadRunning(tg, "ttt");
0531: tArray[i].start();
0532: tArray[i + 3] = new ThreadTest.ThreadRunning(tg1, "ttt");
0533: tArray[i + 3].start();
0534: tArray[i + 6] = new ThreadTest.ThreadRunning(tg2, "ttt");
0535: tArray[i + 6].start();
0536: }
0537: doSleep(50);
0538: // estimate dimension as 3 threads + 1
0539: int estimateLength = 4;
0540: Thread list[];
0541: int count;
0542: while (true) {
0543: list = new Thread[estimateLength];
0544: count = tg.enumerate(list, false);
0545: if (count == estimateLength) {
0546: estimateLength *= 2;
0547: } else {
0548: break;
0549: }
0550: }
0551: int enumerateCount = 0;
0552: for (int i = 0; i < count; i++) {
0553: if (list[i].toString().indexOf("ttt") > 0) {
0554: enumerateCount++;
0555: }
0556: }
0557: for (int i = 0; i < 9; i++) {
0558: tArray[i].stopWork = true;
0559: }
0560: assertEquals("incorrect number of threads in tg", 3,
0561: enumerateCount);
0562: }
0563:
0564: /**
0565: * Verify enumerate(Thread[], true)
0566: */
0567: public void testEnumerateThread_True() {
0568: ThreadGroup tg = new ThreadGroup("tg");
0569: ThreadGroup tg1 = new ThreadGroup(tg, "tg1");
0570: ThreadGroup tg2 = new ThreadGroup(tg1, "tg2");
0571: ThreadTest.ThreadRunning tArray[] = new ThreadTest.ThreadRunning[9];
0572: for (int i = 0; i < 3; i++) {
0573: tArray[i] = new ThreadTest.ThreadRunning(tg, "ttt");
0574: tArray[i].start();
0575: tArray[i + 3] = new ThreadTest.ThreadRunning(tg1, "ttt");
0576: tArray[i + 3].start();
0577: tArray[i + 6] = new ThreadTest.ThreadRunning(tg2, "ttt");
0578: tArray[i + 6].start();
0579: }
0580: doSleep(50);
0581: // estimate dimension as 9 threads + 1
0582: int estimateLength = 10;
0583: Thread list[];
0584: int count;
0585: while (true) {
0586: list = new Thread[estimateLength];
0587: count = tg.enumerate(list, true);
0588: if (count == estimateLength) {
0589: estimateLength *= 2;
0590: } else {
0591: break;
0592: }
0593: }
0594: int enumerateCount = 0;
0595: for (int i = 0; i < count; i++) {
0596: if (list[i].toString().indexOf("ttt") > 0) {
0597: enumerateCount++;
0598: }
0599: }
0600: for (int i = 0; i < 9; i++) {
0601: tArray[i].stopWork = true;
0602: }
0603: assertEquals("incorrect number of threads in tg", 9,
0604: enumerateCount);
0605: }
0606:
0607: /**
0608: * Verify enumerate(ThreadGroup[])
0609: */
0610: public void testEnumerateThreadGroup() {
0611: ThreadGroup tg1 = new ThreadGroup("tg1");
0612: ThreadGroup tg11 = new ThreadGroup(tg1, "tg11");
0613: new ThreadGroup(tg1, "tg12");
0614: new ThreadGroup(tg11, "tg111");
0615: new ThreadGroup(tg11, "tg112");
0616: // estimate dimension as 4 threads + 1
0617: int estimateLength = 5;
0618: ThreadGroup list[];
0619: int count;
0620: while (true) {
0621: list = new ThreadGroup[estimateLength];
0622: count = tg1.enumerate(list);
0623: if (count == estimateLength) {
0624: estimateLength *= 2;
0625: } else {
0626: break;
0627: }
0628: }
0629: int enumerateCount = 0;
0630: for (int i = 0; i < count; i++) {
0631: if (list[i].toString().indexOf("tg1") > 0) {
0632: enumerateCount++;
0633: }
0634: }
0635: assertEquals("incorrect number of thread groups in tg", 4,
0636: enumerateCount);
0637: }
0638:
0639: /**
0640: * Verify enumerate(ThreadGroup[]) when there is a destroyed subgroup
0641: */
0642: public void testEnumerateThreadGroup_Destroyed() {
0643: ThreadGroup tg1 = new ThreadGroup("tg1");
0644: ThreadGroup tg11 = new ThreadGroup(tg1, "tg11");
0645: new ThreadGroup(tg1, "tg12");
0646: ThreadGroup tg111 = new ThreadGroup(tg11, "tg111");
0647: new ThreadGroup(tg11, "tg112");
0648: tg111.destroy();
0649: // estimate dimension as 4 threads + 1
0650: int estimateLength = 5;
0651: ThreadGroup list[];
0652: int count;
0653: while (true) {
0654: list = new ThreadGroup[estimateLength];
0655: count = tg1.enumerate(list);
0656: if (count == estimateLength) {
0657: estimateLength *= 2;
0658: } else {
0659: break;
0660: }
0661: }
0662: int enumerateCount = 0;
0663: for (int i = 0; i < count; i++) {
0664: if (list[i].toString().indexOf("tg1") > 0) {
0665: enumerateCount++;
0666: }
0667: }
0668: assertEquals("incorrect number of thread groups in tg", 3,
0669: enumerateCount);
0670: }
0671:
0672: /**
0673: * Verify enumerate(ThreadGroup[], false)
0674: */
0675: public void testEnumerateThreadGroup_False() {
0676: ThreadGroup tg1 = new ThreadGroup("tg1");
0677: ThreadGroup tg11 = new ThreadGroup(tg1, "tg11");
0678: new ThreadGroup(tg1, "tg12");
0679: new ThreadGroup(tg11, "tg111");
0680: new ThreadGroup(tg11, "tg112");
0681: // estimate dimension as 4 threads + 1
0682: int estimateLength = 5;
0683: ThreadGroup list[];
0684: int count;
0685: while (true) {
0686: list = new ThreadGroup[estimateLength];
0687: count = tg1.enumerate(list, false);
0688: if (count == estimateLength) {
0689: estimateLength *= 2;
0690: } else {
0691: break;
0692: }
0693: }
0694: int enumerateCount = 0;
0695: for (int i = 0; i < count; i++) {
0696: if (list[i].toString().indexOf("tg1") > 0) {
0697: enumerateCount++;
0698: }
0699: }
0700: assertEquals("incorrect number of thread groups in tg", 2,
0701: enumerateCount);
0702: }
0703:
0704: /**
0705: * Verify enumerate(ThreadGroup[], true)
0706: */
0707: public void testEnumerateThreadGroup_True() {
0708: ThreadGroup tg1 = new ThreadGroup("tg1");
0709: ThreadGroup tg11 = new ThreadGroup(tg1, "tg11");
0710: new ThreadGroup(tg1, "tg12");
0711: new ThreadGroup(tg11, "tg111");
0712: new ThreadGroup(tg11, "tg112");
0713: // estimate dimension as 4 threads + 1
0714: int estimateLength = 5;
0715: ThreadGroup list[];
0716: int count;
0717: while (true) {
0718: list = new ThreadGroup[estimateLength];
0719: count = tg1.enumerate(list, true);
0720: if (count == estimateLength) {
0721: estimateLength *= 2;
0722: } else {
0723: break;
0724: }
0725: }
0726: int enumerateCount = 0;
0727: for (int i = 0; i < count; i++) {
0728: if (list[i].toString().indexOf("tg1") > 0) {
0729: enumerateCount++;
0730: }
0731: }
0732: assertEquals("incorrect number of thread groups in tg", 4,
0733: enumerateCount);
0734: }
0735:
0736: /**
0737: * Verify getName()
0738: */
0739: public void testGetName() {
0740: String name = "newGroup";
0741: String childName = "newChildGroup";
0742: ThreadGroup tg = new ThreadGroup(name);
0743: assertEquals("wrong name", name, tg.getName());
0744: ThreadGroup tgChild = new ThreadGroup(tg, childName);
0745: assertEquals("wrong child name", childName, tgChild.getName());
0746: }
0747:
0748: /**
0749: * Verify getParent()
0750: */
0751: public void testGetParent() {
0752: ThreadGroup parent = new ThreadGroup("parent");
0753: ThreadGroup child = new ThreadGroup(parent, "child");
0754: ThreadGroup grandChild = new ThreadGroup(child, "grandChild");
0755: assertSame("improper parent of child", parent, child
0756: .getParent());
0757: assertSame("improper parent of grandchild", child, grandChild
0758: .getParent());
0759: }
0760:
0761: /**
0762: * Verify getParent() of a destroyed group
0763: */
0764: public void testGetParent_DestroyedGroup() {
0765: ThreadGroup parent = new ThreadGroup("parent");
0766: ThreadGroup child = new ThreadGroup(parent, "child");
0767: ThreadGroup grandchild = new ThreadGroup(child, "grandchild");
0768: child.destroy();
0769: assertTrue("child has not been destroyed", child.isDestroyed());
0770: assertTrue("grandchild has not been destroyed", grandchild
0771: .isDestroyed());
0772: assertSame("improper parent of a destroyed group", parent,
0773: child.getParent());
0774: assertSame("a destroyed group should stay parent", child,
0775: grandchild.getParent());
0776: }
0777:
0778: /**
0779: * Verify getParent() of a top-level group
0780: */
0781: public void testGetParent_TopLevelGroup() {
0782: ThreadGroup parent = Thread.currentThread().getThreadGroup()
0783: .getParent();
0784: int groupCount = 1000;
0785: while ((parent != null) && (--groupCount >= 0)) {
0786: parent = parent.getParent();
0787: }
0788: assertNull("top-level group's parent is not null", parent);
0789: }
0790:
0791: /**
0792: * Interrupt a running thread
0793: */
0794: public void testInterrupt() {
0795: ThreadGroup tg = new ThreadGroup("tg");
0796: ThreadGroup tg1 = new ThreadGroup(tg, "tg1");
0797: ThreadTest.ThreadRunning tArray[] = new ThreadTest.ThreadRunning[6];
0798: for (int i = 0; i < 3; i++) {
0799: tArray[i] = new ThreadTest.ThreadRunning(tg, "ttt");
0800: tArray[i].start();
0801: tArray[i + 3] = new ThreadTest.ThreadRunning(tg1, "ttt");
0802: tArray[i + 3].start();
0803: }
0804: doSleep(50);
0805: tg.interrupt();
0806: waitTime = waitDuration;
0807: for (int i = 0; i < 6; i++) {
0808: while (!tArray[i].isInterrupted()
0809: && !(expired = doSleep(10))) {
0810: }
0811: if (expired) {
0812: break;
0813: }
0814: }
0815: for (int i = 0; i < 6; i++) {
0816: tArray[i].stopWork = true;
0817: }
0818: if (expired) {
0819: fail("threads have not been interrupted");
0820: }
0821: }
0822:
0823: /**
0824: * Verify list()
0825: */
0826: public void testList() {
0827: File file = null;
0828: PrintStream newOut = null;
0829: try {
0830: file = File.createTempFile("JUnit_ThreadGroupListTest",
0831: ".tmp");
0832: newOut = new PrintStream(new FileOutputStream(file));
0833: } catch (java.io.IOException e) {
0834: fail("unexpected IOException 1: " + e);
0835: }
0836: try {
0837: System.setOut(newOut);
0838: } catch (SecurityException e) {
0839: return;
0840: }
0841: ThreadGroup tg = new ThreadGroup("tg");
0842: tg.list();
0843: newOut.close();
0844: System.setOut(systemOut);
0845: byte buf[] = new byte[100];
0846: try {
0847: FileInputStream inp = new FileInputStream(file);
0848: inp.read(buf);
0849: inp.close();
0850: } catch (java.io.IOException e) {
0851: fail("unexpected IOException 2: " + e);
0852: }
0853: file.delete();
0854: String toString = "java.lang.ThreadGroup[name=tg,maxpri=";
0855: assertEquals("thread group info has not been printed", 0,
0856: new String(buf).indexOf(toString));
0857: }
0858:
0859: /**
0860: * Verify parentOf()
0861: */
0862: public void testParentOf() {
0863: ThreadGroup tg = new ThreadGroup("tg");
0864: assertTrue("should be true for the argument", tg.parentOf(tg));
0865: ThreadGroup tg1 = new ThreadGroup(tg, "tg1");
0866: assertTrue("tg should be parent of tg1", tg.parentOf(tg1));
0867: ThreadGroup tg2 = new ThreadGroup(tg1, "tg2");
0868: assertTrue("tg1 should be parent of tg2", tg1.parentOf(tg2));
0869: assertTrue("tg should be parent of tg2", tg.parentOf(tg2));
0870: }
0871:
0872: /**
0873: * Verify that maxPriority is inherited by a created subgroup
0874: */
0875: public void testSetMaxPriority_CreateSubgroup() {
0876: ThreadGroup tg = new ThreadGroup("tg");
0877: int pri = Thread.MAX_PRIORITY - 1;
0878: tg.setMaxPriority(pri);
0879: ThreadGroup tg1 = new ThreadGroup(tg, "tg1");
0880: assertEquals("incorrect priority for the created subgroup",
0881: pri, tg1.getMaxPriority());
0882: }
0883:
0884: /**
0885: * Decrease group's maxPriority.
0886: * Verify that threads in the thread group that already have a higher
0887: * priority are not affected.
0888: */
0889: public void testSetMaxPriority_Decrease() {
0890: ThreadGroup group = new ThreadGroup("new");
0891: Thread t1 = new Thread();
0892: int threadPri = t1.getPriority();
0893: int newGroupMaxPri = threadPri - 1;
0894: group.setMaxPriority(newGroupMaxPri);
0895: assertEquals("incorrect group's priority", newGroupMaxPri,
0896: group.getMaxPriority());
0897: assertEquals("thread's priority should not be affected",
0898: threadPri, t1.getPriority());
0899: }
0900:
0901: /**
0902: * Verify that lower maxPriority is set recursively to all subgroups
0903: */
0904: public void testSetMaxPriority_DecreaseRecursively() {
0905: String gName = "tg";
0906: int i;
0907: ThreadGroup tg = new ThreadGroup(gName);
0908: int pri = Thread.MAX_PRIORITY - 1;
0909: tg.setMaxPriority(pri);
0910: for (i = 0; i < 3; i++) {
0911: new ThreadGroup(tg, gName + i);
0912: }
0913: ThreadGroup tg11 = new ThreadGroup(tg, gName + "11");
0914: for (i = 0; i < 3; i++) {
0915: new ThreadGroup(tg11, gName + i);
0916: }
0917: ThreadGroup tg22 = new ThreadGroup(tg11, gName + "22");
0918: for (i = 0; i < 3; i++) {
0919: new ThreadGroup(tg22, gName + i);
0920: }
0921: pri--;
0922: tg.setMaxPriority(pri);
0923: ThreadGroup list[] = new ThreadGroup[11];
0924: tg.enumerate(list);
0925: for (i = 0; i < 11; i++) {
0926: assertEquals("incorrect new priority for the group "
0927: + list[i], pri, list[i].getMaxPriority());
0928: }
0929: }
0930:
0931: /**
0932: * Increase group's maxPriority.
0933: */
0934: public void testSetMaxPriority_Increase() {
0935: ThreadGroup group = new ThreadGroup("new");
0936: group.setMaxPriority(Thread.NORM_PRIORITY);
0937: int newGroupMaxPri = Thread.NORM_PRIORITY + 1;
0938: group.setMaxPriority(newGroupMaxPri);
0939: assertEquals("incorrect group's priority", newGroupMaxPri,
0940: group.getMaxPriority());
0941: }
0942:
0943: /**
0944: * Verify that higher maxPriority is set recursively to all subgroups
0945: */
0946: public void testSetMaxPriority_IncreaseRecursively() {
0947: String gName = "tg";
0948: int i;
0949: ThreadGroup tg = new ThreadGroup(gName);
0950: int pri = Thread.NORM_PRIORITY;
0951: tg.setMaxPriority(pri);
0952: for (i = 0; i < 3; i++) {
0953: new ThreadGroup(tg, gName + i);
0954: }
0955: ThreadGroup tg11 = new ThreadGroup(tg, gName + "11");
0956: for (i = 0; i < 3; i++) {
0957: new ThreadGroup(tg11, gName + i);
0958: }
0959: ThreadGroup tg22 = new ThreadGroup(tg11, gName + "22");
0960: for (i = 0; i < 3; i++) {
0961: new ThreadGroup(tg22, gName + i);
0962: }
0963: pri++;
0964: tg.setMaxPriority(pri);
0965: ThreadGroup list[] = new ThreadGroup[11];
0966: tg.enumerate(list);
0967: for (i = 0; i < 11; i++) {
0968: assertEquals("incorrect new priority for the group "
0969: + list[i], pri, list[i].getMaxPriority());
0970: }
0971: }
0972:
0973: /**
0974: * Try to set maxPriority which is higher than the parent's one
0975: */
0976: public void testSetMaxPriority_HigherParent() {
0977: ThreadGroup parent = new ThreadGroup("par");
0978: int parPriority = Thread.MAX_PRIORITY - 1;
0979: parent.setMaxPriority(parPriority);
0980: assertEquals("incorrect priority received", parPriority, parent
0981: .getMaxPriority());
0982: ThreadGroup child = new ThreadGroup(parent, "ch");
0983: child.setMaxPriority(parPriority - 1);
0984: int newChildPriority = parPriority + 1;
0985: child.setMaxPriority(newChildPriority);
0986: // according to spec the smaller of newChildPriority and parPriority
0987: // should be set
0988: assertEquals("child priority should equal to parent's one",
0989: parPriority, child.getMaxPriority());
0990: }
0991:
0992: /**
0993: * Try to set maxPriority which is out of range
0994: */
0995: public void testSetMaxPriority_OutOfRange() {
0996: ThreadGroup tg = new ThreadGroup("tg");
0997: int curPriority = tg.getMaxPriority();
0998: int newPriority = Thread.MAX_PRIORITY + 1;
0999: tg.setMaxPriority(newPriority);
1000: assertEquals("Assert1: group priority should not change",
1001: curPriority, tg.getMaxPriority());
1002: newPriority = Thread.MIN_PRIORITY - 1;
1003: tg.setMaxPriority(newPriority);
1004: assertEquals(
1005: "Assert2: group priority should be set to Thread.MIN_PRIORITY",
1006: Thread.MIN_PRIORITY, tg.getMaxPriority());
1007: }
1008:
1009: /**
1010: * Verify setMaxPriority() of a system group
1011: */
1012: public void testSetMaxPriority_TopLevelGroup() {
1013: ThreadGroup system = Thread.currentThread().getThreadGroup();
1014: ThreadGroup parent = system.getParent();
1015: int groupCount = 1000;
1016: while (parent != null && --groupCount >= 0) {
1017: system = parent;
1018: parent = system.getParent();
1019: }
1020: int newSystemPriority = system.getMaxPriority() - 1;
1021: try {
1022: system.setMaxPriority(newSystemPriority);
1023: assertEquals("priority has not changed", newSystemPriority,
1024: system.getMaxPriority());
1025: } catch (SecurityException e) {
1026: }
1027: }
1028:
1029: /**
1030: * Verify set/isDaemon()
1031: */
1032: public void testSetDaemon() {
1033: ThreadGroup tg = new ThreadGroup("tg");
1034: assertFalse("a new group should not be daemon", tg.isDaemon());
1035: tg.setDaemon(true);
1036: assertTrue("daemon status has not been set", tg.isDaemon());
1037: ThreadGroup child = new ThreadGroup(tg, "child");
1038: assertTrue("a child of a daemon group should be daemon", child
1039: .isDaemon());
1040: tg.setDaemon(false);
1041: assertFalse("daemon status has not been removed", tg.isDaemon());
1042: }
1043:
1044: /**
1045: * Verifies the suspend/resume() method
1046: */
1047: public void testSuspend() {
1048: ThreadGroup group = new ThreadGroup("Custom group");
1049: TestThread thread = new TestThread(group, "Custom thread");
1050: thread.start();
1051: group.suspend();
1052: assertFalse("the suspended thread should not finish",
1053: thread.finished);
1054: thread.enough = true;
1055: group.resume();
1056: try {
1057: thread.join(1000);
1058: } catch (InterruptedException e) {
1059: fail(INTERRUPTED_MESSAGE);
1060: }
1061: assertTrue("thread has not finished", thread.finished);
1062: }
1063:
1064: /**
1065: * Verify toString() output
1066: */
1067: public void testToString() {
1068: ThreadGroup tg = new ThreadGroup("tg");
1069: String toString = "java.lang.ThreadGroup[name=tg,maxpri=";
1070: assertEquals("incorrect representation", 0, tg.toString()
1071: .indexOf(toString));
1072: }
1073:
1074: public void testUncaughtExceptionHandlers() {
1075: ExceptionHandler defaultHandler = new ExceptionHandler();
1076: Thread.setDefaultUncaughtExceptionHandler(defaultHandler);
1077: Thread t = new Thread("test thread");
1078: Thread.UncaughtExceptionHandler handler = t
1079: .getUncaughtExceptionHandler();
1080: assertNotNull("handler should not be null", handler);
1081: assertSame("thread's thread group expected to be a handler", t
1082: .getThreadGroup(), handler);
1083: handler.uncaughtException(t, new RuntimeException());
1084: assertTrue("Default exception handler was not called",
1085: defaultHandler.wasCalled);
1086: }
1087:
1088: /**
1089: * Verify that thread's explicit exception handler is used
1090: */
1091: public void testUncaughtExceptionHandler_Explicit() {
1092: ExceptionHandler handler = new ExceptionHandler();
1093: Thread testThread = new Thread("test thread") {
1094: public void run() {
1095: throw new RuntimeException();
1096: }
1097: };
1098: testThread.setUncaughtExceptionHandler(handler);
1099: testThread.start();
1100: for (int i = 0; i < 10 && testThread.isAlive(); i++) {
1101: try {
1102: Thread.sleep(50);
1103: } catch (InterruptedException e) {
1104: }
1105: }
1106: assertTrue("Thread's uncaught exception handler wasn't called",
1107: handler.wasCalled);
1108: }
1109:
1110: /**
1111: * Verify that thread's explicit exception handler is used first
1112: * even if a default UncaughtExceptionHandler is set
1113: */
1114: public void testUncaughtException_ExplicitDefault() {
1115: ExceptionHandler deh = new ExceptionHandler();
1116: Thread.setDefaultUncaughtExceptionHandler(deh);
1117: Thread t = new Thread("test thread") {
1118: public void run() {
1119: throw new RuntimeException();
1120: }
1121: };
1122: ExceptionHandler eh = new ExceptionHandler();
1123: t.setUncaughtExceptionHandler(eh);
1124: t.start();
1125: waitTime = waitDuration;
1126: while (!eh.wasCalled && !(expired = doSleep(10))) {
1127: }
1128: assertFalse(
1129: "thread's default exception handler should not been called",
1130: deh.wasCalled);
1131: if (expired) {
1132: fail("thread's exception handler has not been called");
1133: }
1134: }
1135:
1136: /**
1137: * Verify that uncaughtException() method of thread's parent ThreadGroup
1138: * is called even if a default UncaughtExceptionHandler is set
1139: */
1140: public void testUncaughtException_ThreadGroupDefault() {
1141: ExceptionHandler deh = new ExceptionHandler();
1142: Thread.setDefaultUncaughtExceptionHandler(deh);
1143: ThreadGroup grandPa = new ThreadGroup("grandPa");
1144: ThreadGroupHandler parent = new ThreadGroupHandler(grandPa,
1145: "parent");
1146: ThreadGroup child = new ThreadGroup(parent, "tg");
1147: String tName = "testHandler";
1148: Thread t = new Thread(child, tName) {
1149: public void run() {
1150: throw new RuntimeException();
1151: }
1152: };
1153: t.start();
1154: waitTime = waitDuration;
1155: while (!parent.handlerWasCalled && !(expired = doSleep(10))) {
1156: }
1157: assertFalse(
1158: "thread's default exception handler should not been called",
1159: deh.wasCalled);
1160: if (expired) {
1161: fail("threadGroup's uncaughtException() has not been called");
1162: }
1163: }
1164:
1165: /**
1166: * Verify that uncaughtException(Thread, Throwable) method
1167: * where Throwable is ThreadDeath does nothing
1168: */
1169: public void testUncaughtException_ThreadDeath() {
1170: Thread.setDefaultUncaughtExceptionHandler(null);
1171: File file = null;
1172: PrintStream newErr = null;
1173: try {
1174: file = File.createTempFile("JUnit_ThreadUETest1", ".tmp");
1175: newErr = new PrintStream(new FileOutputStream(file));
1176: } catch (java.io.IOException e) {
1177: fail("unexpected IOException 1: " + e);
1178: }
1179: try {
1180: System.setErr(newErr);
1181: } catch (SecurityException e) {
1182: return;
1183: }
1184: Thread t = new Thread("testThreadDeath") {
1185: public void run() {
1186: throw new ThreadDeath();
1187: }
1188: };
1189: t.start();
1190: try {
1191: t.join();
1192: } catch (InterruptedException e) {
1193: fail(INTERRUPTED_MESSAGE);
1194: }
1195: newErr.close();
1196: System.setErr(systemErr);
1197: byte buf[] = new byte[2];
1198: try {
1199: FileInputStream inp = new FileInputStream(file);
1200: inp.read(buf);
1201: inp.close();
1202: } catch (java.io.IOException e) {
1203: fail("unexpected IOException 2: " + e);
1204: }
1205: file.delete();
1206: assertTrue("Uncaught Exception message has not been printed",
1207: buf[0] == 0);
1208: }
1209:
1210: /**
1211: * Verify that uncaughtException(Thread, Throwable) method
1212: * prints a proper message
1213: */
1214: public void testUncaughtException_NullPointerException() {
1215: Thread.setDefaultUncaughtExceptionHandler(null);
1216: File file = null;
1217: PrintStream newErr = null;
1218: try {
1219: file = File.createTempFile("JUnit_ThreadUETest2", ".tmp");
1220: newErr = new PrintStream(new FileOutputStream(file));
1221: } catch (java.io.IOException e) {
1222: fail("unexpected IOException 1: " + e);
1223: }
1224: try {
1225: System.setErr(newErr);
1226: } catch (SecurityException e) {
1227: return;
1228: }
1229: Thread t = new Thread("testNullPointerException") {
1230: public void run() {
1231: throw new NullPointerException();
1232: }
1233: };
1234: t.start();
1235: try {
1236: t.join();
1237: } catch (InterruptedException e) {
1238: fail(INTERRUPTED_MESSAGE);
1239: }
1240: newErr.close();
1241: System.setErr(systemErr);
1242: byte buf[] = new byte[100];
1243: try {
1244: FileInputStream inp = new FileInputStream(file);
1245: inp.read(buf);
1246: inp.close();
1247: } catch (java.io.IOException e) {
1248: fail("unexpected IOException 2: " + e);
1249: }
1250: file.delete();
1251: assertTrue("Uncaught Exception message has not been printed",
1252: new String(buf).indexOf("NullPointerException") > 0);
1253: }
1254: }
|