1561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes/*
2561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes *  Licensed to the Apache Software Foundation (ASF) under one or more
3561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes *  contributor license agreements.  See the NOTICE file distributed with
4561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes *  this work for additional information regarding copyright ownership.
5561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes *  The ASF licenses this file to You under the Apache License, Version 2.0
6561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes *  (the "License"); you may not use this file except in compliance with
7561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes *  the License.  You may obtain a copy of the License at
8561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes *
9561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes *     http://www.apache.org/licenses/LICENSE-2.0
10561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes *
11561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes *  Unless required by applicable law or agreed to in writing, software
12561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes *  distributed under the License is distributed on an "AS IS" BASIS,
13561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes *  See the License for the specific language governing permissions and
15561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes *  limitations under the License.
16561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes */
17561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
18561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughespackage org.apache.harmony.luni.tests.java.lang;
19561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
20561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughesimport java.util.Vector;
21561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
22561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughespublic class ThreadGroupTest extends junit.framework.TestCase {
23561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
24561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes	class MyThread extends Thread {
25561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		public volatile int heartBeat = 0;
26561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
27561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		public MyThread(ThreadGroup group, String name)
28561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes				throws SecurityException, IllegalThreadStateException {
29561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes			super(group, name);
30561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		}
31561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
32561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		@Override
33561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        public void run() {
34561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes			while (true) {
35561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes				heartBeat++;
36561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes				try {
37561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes					Thread.sleep(50);
38561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes				} catch (InterruptedException e) {
39561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes				}
40561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes			}
41561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		}
42561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
43561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		public boolean isActivelyRunning() {
44561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes			long MAX_WAIT = 100;
45561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes			return isActivelyRunning(MAX_WAIT);
46561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		}
47561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
48561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		public boolean isActivelyRunning(long maxWait) {
49561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes			int beat = heartBeat;
50561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes			long start = System.currentTimeMillis();
51561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes			do {
52561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes				Thread.yield();
53561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes				int beat2 = heartBeat;
54561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes				if (beat != beat2) {
55561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    return true;
56561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                }
57561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes			} while (System.currentTimeMillis() - start < maxWait);
58561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes			return false;
59561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		}
60561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
61561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes	}
62561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
63561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes	private ThreadGroup rootThreadGroup = null;
64561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
65561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes	private ThreadGroup initialThreadGroup = null;
66561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
67561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes	/**
68561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes	 * @tests java.lang.ThreadGroup#ThreadGroup(java.lang.String)
69561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes	 */
70561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes	public void test_ConstructorLjava_lang_String() {
71561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		// Test for method java.lang.ThreadGroup(java.lang.String)
72561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
73561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		// Unfortunately we have to use other APIs as well as we test the
74561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		// constructor
75561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
76561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		ThreadGroup newGroup = null;
77561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		ThreadGroup initial = getInitialThreadGroup();
78561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		final String name = "Test name";
79561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		newGroup = new ThreadGroup(name);
80561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		assertTrue(
81561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes				"Has to be possible to create a subgroup of current group using simple constructor",
82561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes				newGroup.getParent() == initial);
83561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		assertTrue("Name has to be correct", newGroup.getName().equals(name));
84561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
85561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		// cleanup
86561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		newGroup.destroy();
87561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
88561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes	}
89561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
90561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes	/**
91561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes	 * @tests java.lang.ThreadGroup#ThreadGroup(java.lang.ThreadGroup,
92561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes	 *        java.lang.String)
93561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes	 */
94561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes	public void test_ConstructorLjava_lang_ThreadGroupLjava_lang_String() {
95561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		// Test for method java.lang.ThreadGroup(java.lang.ThreadGroup,
96561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		// java.lang.String)
97561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
98561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		// Unfortunately we have to use other APIs as well as we test the
99561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		// constructor
100561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
101561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		ThreadGroup newGroup = null;
102561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
103561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		try {
104561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes			newGroup = new ThreadGroup(null, null);
105561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		} catch (NullPointerException e) {
106561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		}
107561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		assertNull("Can't create a ThreadGroup with a null parent",
108561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes				newGroup);
109561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
110561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		newGroup = new ThreadGroup(getInitialThreadGroup(), null);
111561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		assertTrue("Has to be possible to create a subgroup of current group",
112561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes				newGroup.getParent() == Thread.currentThread().getThreadGroup());
113561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
114561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		// Lets start all over
115561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		newGroup.destroy();
116561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
117561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		newGroup = new ThreadGroup(getRootThreadGroup(), "a name here");
118561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		assertTrue("Has to be possible to create a subgroup of root group",
119561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes				newGroup.getParent() == getRootThreadGroup());
120561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
121561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		// Lets start all over
122561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		newGroup.destroy();
123561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
124561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		try {
125561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes			newGroup = new ThreadGroup(newGroup, "a name here");
126561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		} catch (IllegalThreadStateException e) {
127561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes			newGroup = null;
128561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		}
129561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		;
130561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		assertNull("Can't create a subgroup of a destroyed group",
131561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes				newGroup);
132561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes	}
133561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
134561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes	/**
135561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes	 * @tests java.lang.ThreadGroup#activeCount()
136561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes	 */
137561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes	public void test_activeCount() {
138561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		// Test for method int java.lang.ThreadGroup.activeCount()
139561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		ThreadGroup tg = new ThreadGroup("activeCount");
140561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		Thread t1 = new Thread(tg, new Runnable() {
141561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes			public void run() {
142561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes				try {
143561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes					Thread.sleep(5000);
144561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes				} catch (InterruptedException e) {
145561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes				}
146561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes			}
147561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		});
148561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		int count = tg.activeCount();
149561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		assertTrue("wrong active count: " + count, count == 0);
150561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		t1.start();
151561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		count = tg.activeCount();
152561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		assertTrue("wrong active count: " + count, count == 1);
153561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		t1.interrupt();
154561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		try {
155561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes			t1.join();
156561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		} catch (InterruptedException e) {
157561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		}
158561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		// cleanup
159561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		tg.destroy();
160561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes	}
161561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
162561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes	/**
163561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes	 * @tests java.lang.ThreadGroup#destroy()
164561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes	 */
165561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes	public void test_destroy() {
166561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		// Test for method void java.lang.ThreadGroup.destroy()
167561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
168561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		final ThreadGroup originalCurrent = getInitialThreadGroup();
169561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		ThreadGroup testRoot = new ThreadGroup(originalCurrent, "Test group");
170561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		final int DEPTH = 4;
171561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		final Vector<ThreadGroup> subgroups = buildRandomTreeUnder(testRoot, DEPTH);
172561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
173561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		// destroy them all
174561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		testRoot.destroy();
175561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
176561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		for (int i = 0; i < subgroups.size(); i++) {
177561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes			ThreadGroup child = subgroups.elementAt(i);
178561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes			assertEquals("Destroyed child can't have children", 0, child
179561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes					.activeCount());
180561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes			boolean passed = false;
181561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes			try {
182561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes				child.destroy();
183561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes			} catch (IllegalThreadStateException e) {
184561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes				passed = true;
185561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes			}
186561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes			;
187561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes			assertTrue("Destroyed child can't be destroyed again", passed);
188561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		}
189561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
190561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		testRoot = new ThreadGroup(originalCurrent, "Test group (daemon)");
191561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		testRoot.setDaemon(true);
192561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
193561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		ThreadGroup child = new ThreadGroup(testRoot, "daemon child");
194561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
195561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		// If we destroy the last daemon's child, the daemon should get destroyed
196561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		// as well
197561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		child.destroy();
198561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
199561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		boolean passed = false;
200561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		try {
201561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes			child.destroy();
202561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		} catch (IllegalThreadStateException e) {
203561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes			passed = true;
204561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		}
205561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		;
206561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		assertTrue("Daemon should have been destroyed already", passed);
207561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
208561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		passed = false;
209561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		try {
210561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes			testRoot.destroy();
211561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		} catch (IllegalThreadStateException e) {
212561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes			passed = true;
213561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		}
214561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		;
215561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		assertTrue("Daemon parent should have been destroyed automatically",
216561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes				passed);
217561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
218561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		assertTrue(
219561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes				"Destroyed daemon's child should not be in daemon's list anymore",
220561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes				!arrayIncludes(groups(testRoot), child));
221561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		assertTrue("Destroyed daemon should not be in parent's list anymore",
222561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes				!arrayIncludes(groups(originalCurrent), testRoot));
223561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
224561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		testRoot = new ThreadGroup(originalCurrent, "Test group (daemon)");
225561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		testRoot.setDaemon(true);
226561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		Thread noOp = new Thread(testRoot, null, "no-op thread") {
227561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes			@Override
228561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            public void run() {
229561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes			}
230561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		};
231561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		noOp.start();
232561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
233561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		// Wait for the no-op thread to run inside daemon ThreadGroup
234561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		try {
235561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes			noOp.join();
236561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		} catch (InterruptedException ie) {
237561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes			fail("Should not be interrupted");
238561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		}
239561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		;
240561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
241561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		passed = false;
242561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		try {
243561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes			child.destroy();
244561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		} catch (IllegalThreadStateException e) {
245561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes			passed = true;
246561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		}
247561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		;
248561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		assertTrue(
249561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes				"Daemon group should have been destroyed already when last thread died",
250561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes				passed);
251561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
252561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		testRoot = new ThreadGroup(originalCurrent, "Test group (daemon)");
253561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		noOp = new Thread(testRoot, null, "no-op thread") {
254561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes			@Override
255561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            public void run() {
256561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes				try {
257561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes					Thread.sleep(500);
258561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes				} catch (InterruptedException ie) {
259561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes					fail("Should not be interrupted");
260561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes				}
261561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes			}
262561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		};
263561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
264561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		// Has to execute the next lines in an interval < the sleep interval of
265561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		// the no-op thread
266561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		noOp.start();
267561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		passed = false;
268561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		try {
269561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes			testRoot.destroy();
270561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		} catch (IllegalThreadStateException its) {
271561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes			passed = true;
272561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		}
273561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		assertTrue("Can't destroy a ThreadGroup that has threads", passed);
274561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
275561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		// But after the thread dies, we have to be able to destroy the thread
276561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		// group
277561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		try {
278561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes			noOp.join();
279561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		} catch (InterruptedException ie) {
280561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes			fail("Should not be interrupted");
281561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		}
282561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		;
283561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		passed = true;
284561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		try {
285561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes			testRoot.destroy();
286561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		} catch (IllegalThreadStateException its) {
287561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes			passed = false;
288561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		}
289561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		assertTrue(
290561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes				"Should be able to destroy a ThreadGroup that has no threads",
291561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes				passed);
292561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
293561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes	}
294561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
295561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes	/**
296561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes	 * @tests java.lang.ThreadGroup#destroy()
297561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes	 */
298561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes	public void test_destroy_subtest0() {
299561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		ThreadGroup group1 = new ThreadGroup("test_destroy_subtest0");
300561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		group1.destroy();
301561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		try {
302561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes			new Thread(group1, "test_destroy_subtest0");
303561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes			fail("should throw IllegalThreadStateException");
304561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		} catch (IllegalThreadStateException e) {
305561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		}
306561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes	}
307561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
308561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes	/**
309561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes	 * @tests java.lang.ThreadGroup#getMaxPriority()
310561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes	 */
311561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes	public void test_getMaxPriority() {
312561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		// Test for method int java.lang.ThreadGroup.getMaxPriority()
313561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
314561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		final ThreadGroup originalCurrent = getInitialThreadGroup();
315561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		ThreadGroup testRoot = new ThreadGroup(originalCurrent, "Test group");
316561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
317561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		boolean passed = true;
318561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		try {
319561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes			testRoot.setMaxPriority(Thread.MIN_PRIORITY);
320561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		} catch (IllegalArgumentException iae) {
321561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes			passed = false;
322561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		}
323561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		assertTrue("Should be able to set priority", passed);
324561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
325561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		assertTrue("New value should be the same as we set", testRoot
326561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes				.getMaxPriority() == Thread.MIN_PRIORITY);
327561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
328561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		testRoot.destroy();
329561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
330561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes	}
331561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
332561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes	/**
333561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes	 * @tests java.lang.ThreadGroup#getName()
334561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes	 */
335561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes	public void test_getName() {
336561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		// Test for method java.lang.String java.lang.ThreadGroup.getName()
337561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
338561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		final ThreadGroup originalCurrent = getInitialThreadGroup();
339561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		final String name = "Test group";
340561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		final ThreadGroup testRoot = new ThreadGroup(originalCurrent, name);
341561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
342561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		assertTrue("Setting a name&getting does not work", testRoot.getName()
343561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes				.equals(name));
344561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
345561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		testRoot.destroy();
346561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
347561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes	}
348561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
349561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes	/**
350561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes	 * @tests java.lang.ThreadGroup#getParent()
351561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes	 */
352561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes	public void test_getParent() {
353561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		// Test for method java.lang.ThreadGroup
354561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		// java.lang.ThreadGroup.getParent()
355561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
356561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		final ThreadGroup originalCurrent = getInitialThreadGroup();
357561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		ThreadGroup testRoot = new ThreadGroup(originalCurrent, "Test group");
358561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
359561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		assertTrue("Parent is wrong", testRoot.getParent() == originalCurrent);
360561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
361561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		// Create some groups, nested some levels.
362561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		final int TOTAL_DEPTH = 5;
363561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		ThreadGroup current = testRoot;
364561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		Vector<ThreadGroup> groups = new Vector<ThreadGroup>();
365561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		// To maintain the invariant that a thread in the Vector is parent
366561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		// of the next one in the collection (and child of the previous one)
367561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		groups.addElement(testRoot);
368561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
369561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		for (int i = 0; i < TOTAL_DEPTH; i++) {
370561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes			current = new ThreadGroup(current, "level " + i);
371561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes			groups.addElement(current);
372561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		}
373561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
374561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		// Now we walk the levels down, checking if parent is ok
375561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		for (int i = 1; i < groups.size(); i++) {
376561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes			current = groups.elementAt(i);
377561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes			ThreadGroup previous = groups.elementAt(i - 1);
378561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes			assertTrue("Parent is wrong", current.getParent() == previous);
379561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		}
380561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
381561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		testRoot.destroy();
382561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes	}
383561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
384561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes	/**
385561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes	 * @tests java.lang.ThreadGroup#isDaemon()
386561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes	 */
387561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes	public void test_isDaemon() {
388561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		// Test for method boolean java.lang.ThreadGroup.isDaemon()
389561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
390561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		daemonTests();
391561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
392561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes	}
393561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
394561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes	/**
395561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes	 * @tests java.lang.ThreadGroup#list()
396561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes	 */
397561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes	public void test_list() {
398561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		// Test for method void java.lang.ThreadGroup.list()
399561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
400561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		final ThreadGroup originalCurrent = getInitialThreadGroup();
401561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		// wipeSideEffectThreads destroy all side effect of threads created in
402561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		// java.lang.Thread
403561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		boolean result = wipeSideEffectThreads(originalCurrent);
404561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		if (result == false) {
405561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            fail("wipe threads in test_list() not successful");
406561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        }
407561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		final ThreadGroup testRoot = new ThreadGroup(originalCurrent,
408561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes				"Test group");
409561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
410561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		// First save the original System.out
411561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		java.io.PrintStream originalOut = System.out;
412561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
413561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		try {
414561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes			java.io.ByteArrayOutputStream contentsStream = new java.io.ByteArrayOutputStream(
415561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes					100);
416561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes			java.io.PrintStream newOut = new java.io.PrintStream(contentsStream);
417561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
418561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes			// We have to "redirect" System.out to test the method 'list'
419561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes			System.setOut(newOut);
420561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
421561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes			originalCurrent.list();
422561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
423561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes			/*
424561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes			 * The output has to look like this
425fc95c99cfa4921fef424f3f411d013b821589e69Elliott Hughes			 *
426561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes			 * java.lang.ThreadGroup[name=main,maxpri=10] Thread[main,5,main]
427561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes			 * java.lang.ThreadGroup[name=Test group,maxpri=10]
428fc95c99cfa4921fef424f3f411d013b821589e69Elliott Hughes			 *
429561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes			 */
430561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
431561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            String contents = new String(contentsStream.toByteArray());
432561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            boolean passed = (contents.indexOf("ThreadGroup[name=main") != -1) &&
433561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                             (contents.indexOf("Thread[") != -1) &&
434561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                             (contents.indexOf("ThreadGroup[name=Test group") != -1);
435fc95c99cfa4921fef424f3f411d013b821589e69Elliott Hughes            assertTrue("'list()' does not print expected contents. "
436561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    + "Result from list: "
437561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    + contents, passed);
438561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes			// Do proper cleanup
439561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes			testRoot.destroy();
440561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
441561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		} finally {
442561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes			// No matter what, we need to restore the original System.out
443561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes			System.setOut(originalOut);
444561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		}
445561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
446561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes	}
447561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
448561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes	/**
449561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes	 * @tests java.lang.ThreadGroup#parentOf(java.lang.ThreadGroup)
450561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes	 */
451561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes	public void test_parentOfLjava_lang_ThreadGroup() {
452561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		// Test for method boolean
453561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		// java.lang.ThreadGroup.parentOf(java.lang.ThreadGroup)
454561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
455561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		final ThreadGroup originalCurrent = getInitialThreadGroup();
456561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		final ThreadGroup testRoot = new ThreadGroup(originalCurrent,
457561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes				"Test group");
458561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		final int DEPTH = 4;
459561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		buildRandomTreeUnder(testRoot, DEPTH);
460561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
461561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		final ThreadGroup[] allChildren = allGroups(testRoot);
462561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		for (ThreadGroup element : allChildren) {
463561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes			assertTrue("Have to be parentOf all children", testRoot
464561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes					.parentOf(element));
465561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		}
466561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
467561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		assertTrue("Have to be parentOf itself", testRoot.parentOf(testRoot));
468561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
469561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		testRoot.destroy();
470561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		assertTrue("Parent can't have test group as subgroup anymore",
471561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes				!arrayIncludes(groups(testRoot.getParent()), testRoot));
472561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes	}
473561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
474561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes	/**
475561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes	 * @tests java.lang.ThreadGroup#setDaemon(boolean)
476561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes	 */
477561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes	public void test_setDaemonZ() {
478561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		// Test for method void java.lang.ThreadGroup.setDaemon(boolean)
479561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
480561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		daemonTests();
481561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
482561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes	}
483561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
484561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    /*
485561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     * @tests java.lang.ThreadGroupt#setDaemon(boolean)
486561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes     */
487561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    public void test_setDaemon_Parent_Child() {
488561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        ThreadGroup ptg = new ThreadGroup("Parent");
489561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        ThreadGroup ctg = new ThreadGroup(ptg, "Child");
490561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
491561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        ctg.setDaemon(true);
492561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        assertTrue(ctg.isDaemon());
493561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
494561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        ctg.setDaemon(false);
495561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        assertFalse(ctg.isDaemon());
496561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
497561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        ptg.setDaemon(true);
498561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        assertFalse(ctg.isDaemon());
499561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
500561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        ptg.setDaemon(false);
501561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        assertFalse(ctg.isDaemon());
502561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    }
503561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
504561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes	/**
505561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes	 * @tests java.lang.ThreadGroup#setMaxPriority(int)
506561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes	 */
507561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes	public void test_setMaxPriorityI() {
508561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		// Test for method void java.lang.ThreadGroup.setMaxPriority(int)
509561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
510561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		final ThreadGroup originalCurrent = getInitialThreadGroup();
511561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		ThreadGroup testRoot = new ThreadGroup(originalCurrent, "Test group");
512561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
513561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		boolean passed;
514561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
515561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
516561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
517561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		int currentMax = testRoot.getMaxPriority();
518561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		testRoot.setMaxPriority(Thread.MAX_PRIORITY + 1);
519561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		passed = testRoot.getMaxPriority() == currentMax;
520561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		assertTrue(
521561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes				"setMaxPriority: Any value higher than the current one is ignored. Before: "
522561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes						+ currentMax + " , after: " + testRoot.getMaxPriority(),
523561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes				passed);
524561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
525561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
526561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
527561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		currentMax = testRoot.getMaxPriority();
528561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		testRoot.setMaxPriority(Thread.MIN_PRIORITY - 1);
529561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		passed = testRoot.getMaxPriority() == Thread.MIN_PRIORITY;
530561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		assertTrue(
531561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes				"setMaxPriority: Any value smaller than MIN_PRIORITY is adjusted to MIN_PRIORITY. Before: "
532561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes						+ currentMax + " , after: " + testRoot.getMaxPriority(),
533561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes				passed);
534561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
535561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
536561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
537561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		testRoot.destroy();
538561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		testRoot = new ThreadGroup(originalCurrent, "Test group");
539561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
540561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		// Create some groups, nested some levels. Each level will have maxPrio
541561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		// 1 unit smaller than the parent's. However, there can't be a group
542561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		// with priority < Thread.MIN_PRIORITY
543561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		final int TOTAL_DEPTH = testRoot.getMaxPriority() - Thread.MIN_PRIORITY
544561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes				- 2;
545561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		ThreadGroup current = testRoot;
546561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		for (int i = 0; i < TOTAL_DEPTH; i++) {
547561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes			current = new ThreadGroup(current, "level " + i);
548561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		}
549561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
550561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		// Now we walk the levels down, changing the maxPrio and later verifying
551561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		// that the value is indeed 1 unit smaller than the parent's maxPrio.
552561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		int maxPrio, parentMaxPrio;
553561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		current = testRoot;
554561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
555561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		// To maintain the invariant that when we are to modify a child,
556561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		// its maxPriority is always 1 unit smaller than its parent's.
557561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		// We have to set it for the root manually, and the loop does the rest
558561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		// for all the other sub-levels
559561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		current.setMaxPriority(current.getParent().getMaxPriority() - 1);
560561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
561561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		for (int i = 0; i < TOTAL_DEPTH; i++) {
562561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes			maxPrio = current.getMaxPriority();
563561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes			parentMaxPrio = current.getParent().getMaxPriority();
564561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
565561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes			ThreadGroup[] children = groups(current);
566561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes			assertEquals("Can only have 1 subgroup", 1, children.length);
567561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes			current = children[0];
568561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes			assertTrue(
569561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes					"Had to be 1 unit smaller than parent's priority in iteration="
570561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes							+ i + " checking->" + current,
571561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes					maxPrio == parentMaxPrio - 1);
572561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes			current.setMaxPriority(maxPrio - 1);
573561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
574561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes			// The next test is sort of redundant, since in next iteration it
575561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes			// will be the parent tGroup, so the test will be done.
576561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes			assertTrue("Had to be possible to change max priority", current
577561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes					.getMaxPriority() == maxPrio - 1);
578561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		}
579561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
580561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		assertTrue(
581561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes				"Priority of leaf child group has to be much smaller than original root group",
582561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes				current.getMaxPriority() == testRoot.getMaxPriority()
583561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes						- TOTAL_DEPTH);
584561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
585561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		testRoot.destroy();
586561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
587561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
588561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
589561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		passed = true;
590561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		testRoot = new ThreadGroup(originalCurrent, "Test group");
591561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		try {
592561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes			testRoot.setMaxPriority(Thread.MAX_PRIORITY);
593561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		} catch (IllegalArgumentException iae) {
594561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes			passed = false;
595561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		}
596561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		assertTrue(
597561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes				"Max Priority = Thread.MAX_PRIORITY should be possible if the test is run with default system ThreadGroup as root",
598561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes				passed);
599561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		testRoot.destroy();
600561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes	}
601561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
602561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes	/**
603561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes	 * @tests java.lang.ThreadGroup#uncaughtException(java.lang.Thread,
604561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes	 *        java.lang.Throwable)
605561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes	 */
606561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes	@SuppressWarnings("deprecation")
607561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    public void test_uncaughtExceptionLjava_lang_ThreadLjava_lang_Throwable() {
608561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		// Test for method void
609561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		// java.lang.ThreadGroup.uncaughtException(java.lang.Thread,
610561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		// java.lang.Throwable)
611561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
612561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		final ThreadGroup originalCurrent = getInitialThreadGroup();
613561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
614561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		// indices for the array defined below
615561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		final int TEST_DEATH = 0;
616561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		final int TEST_OTHER = 1;
617561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		final int TEST_EXCEPTION_IN_UNCAUGHT = 2;
618561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		final int TEST_OTHER_THEN_DEATH = 3;
619561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		final int TEST_FORCING_THROW_THREAD_DEATH = 4;
620561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		final int TEST_KILLING = 5;
621561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		final int TEST_DEATH_AFTER_UNCAUGHT = 6;
622561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
623561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		final boolean[] passed = new boolean[] { false, false, false, false,
624561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes				false, false, false };
625561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
626561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		ThreadGroup testRoot;
627561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		Thread thread;
628561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
629561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		// Our own exception class
630561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		class TestException extends RuntimeException {
631561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            private static final long serialVersionUID = 1L;
632561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		}
633561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
634561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
635561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		// - - - - - - -
636561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		testRoot = new ThreadGroup(originalCurrent,
637561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes				"Test killing a Thread, forcing it to throw ThreadDeath") {
638561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes			@Override
639561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            public void uncaughtException(Thread t, Throwable e) {
640561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes				if (e instanceof ThreadDeath) {
641561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    passed[TEST_KILLING] = true;
642561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                }
643561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes				// always forward, any exception
644561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes				super.uncaughtException(t, e);
645561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes			}
646561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		};
647561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
648561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
649561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		// - - - - - - -
650561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		testRoot = new ThreadGroup(originalCurrent,
651561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes				"Test Forcing a throw of ThreadDeath") {
652561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes			@Override
653561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            public void uncaughtException(Thread t, Throwable e) {
654561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes				if (e instanceof ThreadDeath) {
655561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    passed[TEST_FORCING_THROW_THREAD_DEATH] = true;
656561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                }
657561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes				// always forward, any exception
658561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes				super.uncaughtException(t, e);
659561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes			}
660561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		};
661561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
662561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		// Test if a Thread tells its ThreadGroup about ThreadDeath
663561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		thread = new Thread(testRoot, null, "suicidal thread") {
664561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes			@Override
665561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            public void run() {
666561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes				throw new ThreadDeath();
667561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes			}
668561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		};
669561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		thread.start();
670561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		try {
671561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes			thread.join();
672561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		} catch (InterruptedException ie) {
673561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes			fail("Should not have been interrupted");
674561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		}
675561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		testRoot.destroy();
676561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		assertTrue(
677561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes				"Any thread should notify its ThreadGroup about its own death, even if suicide:"
678561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes						+ testRoot, passed[TEST_FORCING_THROW_THREAD_DEATH]);
679561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
680561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
681561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		// - - - - - - -
682561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
683561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		testRoot = new ThreadGroup(originalCurrent, "Test ThreadDeath") {
684561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes			@Override
685561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            public void uncaughtException(Thread t, Throwable e) {
686561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes				passed[TEST_DEATH] = false;
687561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes				// always forward, any exception
688561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes				super.uncaughtException(t, e);
689561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes			}
690561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		};
691561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
692561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		// Test if a Thread tells its ThreadGroup about ThreadDeath
693561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		passed[TEST_DEATH] = true;
694561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		thread = new Thread(testRoot, null, "no-op thread");
695561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		thread.start();
696561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		try {
697561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes			thread.join();
698561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		} catch (InterruptedException ie) {
699561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes			fail("Should not have been interrupted");
700561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		}
701561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		testRoot.destroy();
702561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		assertTrue("A thread should not call uncaughtException when it dies:"
703561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes				+ testRoot, passed[TEST_DEATH]);
704561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
705561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
706561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		// - - - - - - -
707561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
708561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		testRoot = new ThreadGroup(originalCurrent, "Test other Exception") {
709561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes			@Override
710561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            public void uncaughtException(Thread t, Throwable e) {
711561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes				if (e instanceof TestException) {
712561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    passed[TEST_OTHER] = true;
713561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                } else {
714561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    // only forward exceptions other than our test
715561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes					super.uncaughtException(t, e);
716561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                }
717561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes			}
718561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		};
719561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
720561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		// Test if a Thread tells its ThreadGroup about an Exception
721561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		thread = new Thread(testRoot, null, "no-op thread") {
722561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes			@Override
723561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            public void run() {
724561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes				throw new TestException();
725561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes			}
726561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		};
727561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		thread.start();
728561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		try {
729561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes			thread.join();
730561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		} catch (InterruptedException ie) {
731561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes			fail("Should not have been interrupted");
732561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		}
733561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		testRoot.destroy();
734561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		assertTrue(
735561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes				"Any thread should notify its ThreadGroup about an uncaught exception:"
736561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes						+ testRoot, passed[TEST_OTHER]);
737561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
738561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
739561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		// - - - - - - -
740561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
741561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		// Our own uncaught exception class
742561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		class UncaughtException extends TestException {
743561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            private static final long serialVersionUID = 1L;
744561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		}
745561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
746561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		testRoot = new ThreadGroup(originalCurrent,
747561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes				"Test Exception in uncaught exception") {
748561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes			@Override
749561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            public void uncaughtException(Thread t, Throwable e) {
750561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes				if (e instanceof TestException) {
751561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes					passed[TEST_EXCEPTION_IN_UNCAUGHT] = true;
752561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes					// Let's simulate an error inside our uncaughtException
753561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes					// method.
754561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes					// This should be no-op according to the spec
755561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes					throw new UncaughtException();
756561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes				}
757561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                // only forward exceptions other than our test
758561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                super.uncaughtException(t, e);
759561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes			}
760561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		};
761561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
762561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		// Test if an Exception in uncaughtException is really a no-op
763561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		thread = new Thread(testRoot, null, "no-op thread") {
764561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes			@Override
765561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            public void run() {
766561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes				try {
767561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes					throw new TestException();
768561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes				} catch (UncaughtException ue) {
769561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes					// any exception in my ThreadGroup's uncaughtException must
770561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes					// not be propagated.
771561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes					// If it gets propagated and we detected that, the test failed
772561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes					passed[TEST_EXCEPTION_IN_UNCAUGHT] = false;
773561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes				}
774561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes			}
775561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		};
776561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		thread.start();
777561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		try {
778561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes			thread.join();
779561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		} catch (InterruptedException ie) {
780561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes			fail("Should not have been interrupted");
781561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		}
782561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		testRoot.destroy();
783561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		assertTrue(
784561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes				"Any uncaughtException in uncaughtException should be no-op:"
785561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes						+ testRoot, passed[TEST_EXCEPTION_IN_UNCAUGHT]);
786561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
787561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
788561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		// - - - - - - -
789561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
790561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		// This is a mix of 2 of the tests above. It is assumed that ThreadDeath
791561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		// and any random exception do work , tested separately. Now we test
792561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		// if after an uncaughtException is forwarded to the ThreadGroup and
793561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		// the Thread dies, if ThreadDeath is also forwarded. It should be
794561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		// (so that a ThreadGroup can know its Thread died)
795561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		testRoot = new ThreadGroup(originalCurrent,
796561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes				"Test Uncaught followed by ThreadDeath") {
797561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes			@Override
798561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            public void uncaughtException(Thread t, Throwable e) {
799561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes				if (e instanceof ThreadDeath) {
800561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    passed[TEST_DEATH_AFTER_UNCAUGHT] = true;
801561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                }
802561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes				if (e instanceof TestException) {
803561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    passed[TEST_OTHER_THEN_DEATH] = true;
804561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                } else {
805561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    // only forward exceptions other than our test
806561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes					super.uncaughtException(t, e);
807561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                }
808561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes			}
809561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		};
810561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
811561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		// Test if a Thread tells its ThreadGroup about an Exception and also
812561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		// ThreadDeath
813561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		thread = new Thread(testRoot, null, "no-op thread") {
814561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes			@Override
815561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            public void run() {
816561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes				throw new TestException();
817561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes			}
818561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		};
819561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		thread.start();
820561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		try {
821561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes			thread.join();
822561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		} catch (InterruptedException ie) {
823561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes			fail("Should not have been interrupted");
824561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		}
825561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		testRoot.destroy();
826561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes	}
827561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
828561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes	@Override
829561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    protected void setUp() {
830561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		initialThreadGroup = Thread.currentThread().getThreadGroup();
831561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		rootThreadGroup = initialThreadGroup;
832561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		while (rootThreadGroup.getParent() != null) {
833561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            rootThreadGroup = rootThreadGroup.getParent();
834561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        }
835561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes	}
836561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
837561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes	@Override
838561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    protected void tearDown() {
839561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		try {
840561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes			// Give the threads a chance to die.
841561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes			Thread.sleep(50);
842561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		} catch (InterruptedException e) {
843561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		}
844561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes	}
845561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
846561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes	private Thread[] threads(ThreadGroup parent) {
847561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		// No API to get the count of immediate children only ?
848561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		int count = parent.activeCount();
849561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		Thread[] all = new Thread[count];
850561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		int actualSize = parent.enumerate(all, false);
851561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		Thread[] result;
852561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		if (actualSize == all.length) {
853561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            result = all;
854561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        } else {
855561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes			result = new Thread[actualSize];
856561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes			System.arraycopy(all, 0, result, 0, actualSize);
857561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		}
858561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
859561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		return result;
860561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
861561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes	}
862561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
863561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes	private ThreadGroup getInitialThreadGroup() {
864561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		return initialThreadGroup;
865561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes	}
866561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
867561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes	private ThreadGroup[] allGroups(ThreadGroup parent) {
868561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		int count = parent.activeGroupCount();
869561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		ThreadGroup[] all = new ThreadGroup[count];
870561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		parent.enumerate(all, true);
871561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		return all;
872561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes	}
873561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
874561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes	private void daemonTests() {
875561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		// Test for method void java.lang.ThreadGroup.setDaemon(boolean)
876561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
877561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		final ThreadGroup originalCurrent = getInitialThreadGroup();
878561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		final ThreadGroup testRoot = new ThreadGroup(originalCurrent,
879561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes				"Test group");
880561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
881561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		testRoot.setDaemon(true);
882561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		assertTrue("Setting daemon&getting does not work", testRoot.isDaemon());
883561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
884561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		testRoot.setDaemon(false);
885561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		assertTrue("Setting daemon&getting does not work", !testRoot.isDaemon());
886561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
887561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		testRoot.destroy();
888561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
889561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes	}
890561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
891561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes	private boolean wipeAllThreads(final ThreadGroup aGroup) {
892561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		boolean ok = true;
893561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		Thread[] threads = threads(aGroup);
894561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		for (Thread t : threads) {
895561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes			ok = ok && wipeThread(t);
896561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		}
897561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
898561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		// Recursively for subgroups (if any)
899561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		ThreadGroup[] children = groups(aGroup);
900561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		for (ThreadGroup element : children) {
901561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes			ok = ok && wipeAllThreads(element);
902561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		}
903561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
904561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		return ok;
905561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
906561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes	}
907561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
908561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes	private boolean wipeSideEffectThreads(ThreadGroup aGroup) {
909561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		boolean ok = true;
910561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		Thread[] threads = threads(aGroup);
911561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		for (Thread t : threads) {
912561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes			if (t.getName().equals("SimpleThread")
913561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes					|| t.getName().equals("Bogus Name")
914561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes					|| t.getName().equals("Testing")
915561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes					|| t.getName().equals("foo")
916561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes					|| t.getName().equals("Test Group")
917561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes					|| t.getName().equals("Squawk")
918561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes					|| t.getName().equals("Thread-1")
919561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes					|| t.getName().equals("firstOne")
920561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes					|| t.getName().equals("secondOne")
921561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes					|| t.getName().equals("Thread-16")
922561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes					|| t.getName().equals("Thread-14")) {
923561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                ok = ok && wipeThread(t);
924561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            }
925561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		}
926561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
927561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		// Recursively for subgroups (if any)
928561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		ThreadGroup[] children = groups(aGroup);
929561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
930561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		for (ThreadGroup element : children) {
931561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes			ok = ok && wipeSideEffectThreads(element);
932561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes			if (element.getName().equals("Test Group")
933561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes					|| element.getName().equals("foo")
934561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes					|| element.getName().equals("jp")) {
935561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                element.destroy();
936561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            }
937561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		}
938561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		try {
939561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes			// Give the threads a chance to die.
940561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes			Thread.sleep(50);
941561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		} catch (InterruptedException e) {
942561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		}
943561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		return ok;
944561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes	}
945561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
946561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes	private void asyncBuildRandomTreeUnder(final ThreadGroup aGroup,
947561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes			final int depth, final Vector<ThreadGroup> allCreated) {
948561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		if (depth <= 0) {
949561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            return;
950561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        }
951561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
952561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		final int maxImmediateSubgroups = random(3);
953561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		for (int i = 0; i < maxImmediateSubgroups; i++) {
954561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes			final int iClone = i;
955561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes			final String name = " Depth = " + depth + ",N = " + iClone
956561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes					+ ",Vector size at creation: " + allCreated.size();
957561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes			// Use concurrency to maximize chance of exposing concurrency bugs
958561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes			// in ThreadGroups
959561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes			Thread t = new Thread(aGroup, name) {
960561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes				@Override
961561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                public void run() {
962561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes					ThreadGroup newGroup = new ThreadGroup(aGroup, name);
963561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes					allCreated.addElement(newGroup);
964561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes					asyncBuildRandomTreeUnder(newGroup, depth - 1, allCreated);
965561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes				}
966561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes			};
967561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes			t.start();
968561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		}
969561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
970561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes	}
971561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
972561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes	private Vector<ThreadGroup> asyncBuildRandomTreeUnder(final ThreadGroup aGroup,
973561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes			final int depth) {
974561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		Vector<ThreadGroup> result = new Vector<ThreadGroup>();
975561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		asyncBuildRandomTreeUnder(aGroup, depth, result);
976561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		return result;
977561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
978561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes	}
979561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
980561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes	private boolean allSuspended(Vector<MyThread> threads) {
981561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		for (int i = 0; i < threads.size(); i++) {
982561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes			MyThread t = threads.elementAt(i);
983561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes			if (t.isActivelyRunning()) {
984561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                return false;
985561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            }
986561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		}
987561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
988561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		return true;
989561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
990561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes	}
991561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
992561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes	private ThreadGroup[] groups(ThreadGroup parent) {
993561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		// No API to get the count of immediate children only ?
994561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		int count = parent.activeGroupCount();
995561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		ThreadGroup[] all = new ThreadGroup[count];
996561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		parent.enumerate(all, false);
997561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		// Now we may have nulls in the array, we must find the actual size
998561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		int actualSize = 0;
999561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		for (; actualSize < all.length; actualSize++) {
1000561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes			if (all[actualSize] == null) {
1001561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                break;
1002561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            }
1003561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		}
1004561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		ThreadGroup[] result;
1005561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		if (actualSize == all.length) {
1006561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            result = all;
1007561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        } else {
1008561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes			result = new ThreadGroup[actualSize];
1009561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes			System.arraycopy(all, 0, result, 0, actualSize);
1010561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		}
1011561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
1012561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		return result;
1013561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
1014561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes	}
1015561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
1016561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes	private Vector<MyThread> populateGroupsWithThreads(final ThreadGroup aGroup,
1017561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes			final int threadCount) {
1018561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		Vector<MyThread> result = new Vector<MyThread>();
1019561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		populateGroupsWithThreads(aGroup, threadCount, result);
1020561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		return result;
1021561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
1022561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes	}
1023561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
1024561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes	private void populateGroupsWithThreads(final ThreadGroup aGroup,
1025561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes			final int threadCount, final Vector<MyThread> allCreated) {
1026561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		for (int i = 0; i < threadCount; i++) {
1027561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes			final int iClone = i;
1028561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes			final String name = "(MyThread)N =" + iClone + "/" + threadCount
1029561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes					+ " ,Vector size at creation: " + allCreated.size();
1030561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
1031561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes			MyThread t = new MyThread(aGroup, name);
1032561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes			allCreated.addElement(t);
1033561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		}
1034561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
1035561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		// Recursively for subgroups (if any)
1036561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		ThreadGroup[] children = groups(aGroup);
1037561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		for (ThreadGroup element : children) {
1038561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes			populateGroupsWithThreads(element, threadCount, allCreated);
1039561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		}
1040561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
1041561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes	}
1042561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
1043561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes	private int random(int max) {
1044561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
1045561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		return 1 + ((new Object()).hashCode() % max);
1046561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
1047561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes	}
1048561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
1049561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes	@SuppressWarnings("deprecation")
1050561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes    private boolean wipeThread(Thread t) {
1051561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		t.stop();
1052561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		try {
1053561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes			t.join(1000);
1054561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		} catch (InterruptedException ie) {
1055561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes			fail("Should not have been interrupted");
1056561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		}
1057fc95c99cfa4921fef424f3f411d013b821589e69Elliott Hughes		// The thread had plenty (subjective) of time to die so there
1058561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		// is a problem.
1059561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		if (t.isAlive()) {
1060561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            return false;
1061561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes        }
1062561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
1063561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		return true;
1064561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes	}
1065561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
1066561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes	private Vector<ThreadGroup> buildRandomTreeUnder(ThreadGroup aGroup, int depth) {
1067561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		Vector<ThreadGroup> result = asyncBuildRandomTreeUnder(aGroup, depth);
1068561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		while (true) {
1069561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes			int sizeBefore = result.size();
1070561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes			try {
1071561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes				Thread.sleep(1000);
1072561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes				int sizeAfter = result.size();
1073561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes				// If no activity for a while, we assume async building may be
1074561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes				// done.
1075561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes				if (sizeBefore == sizeAfter) {
1076561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    // It can only be done if no more threads. Unfortunately we
1077561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes					// are relying on this API to work as well.
1078561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes					// If it does not, we may loop forever.
1079561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes					if (aGroup.activeCount() == 0) {
1080561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                        break;
1081561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                    }
1082561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                }
1083561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes			} catch (InterruptedException e) {
1084561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes			}
1085561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		}
1086561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		return result;
1087561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
1088561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes	}
1089561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
1090561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes	private boolean arrayIncludes(Object[] array, Object toTest) {
1091561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		for (Object element : array) {
1092561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes			if (element == toTest) {
1093561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes                return true;
1094561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes            }
1095561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		}
1096561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
1097561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		return false;
1098561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes	}
1099561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
1100561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes	protected void myassertTrue(String msg, boolean b) {
1101561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		// This method is defined here just to solve a visibility problem
1102561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		// of protected methods with inner types
1103561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		assertTrue(msg, b);
1104561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes	}
1105561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
1106561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes	private ThreadGroup getRootThreadGroup() {
1107561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes		return rootThreadGroup;
1108561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes
1109561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes	}
1110561ee011997c6c2f1befbfaa9d5f0a99771c1d63Elliott Hughes}
1111