You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by te...@apache.org on 2006/03/15 12:47:39 UTC

svn commit: r386058 [22/49] - in /incubator/harmony/enhanced/classlib/trunk: make/ modules/archive/make/common/ modules/archive/src/test/java/tests/ modules/archive/src/test/java/tests/api/ modules/archive/src/test/java/tests/api/java/ modules/archive/...

Added: incubator/harmony/enhanced/classlib/trunk/modules/luni/src/test/java/tests/api/java/lang/SystemTest.java
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/classlib/trunk/modules/luni/src/test/java/tests/api/java/lang/SystemTest.java?rev=386058&view=auto
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/luni/src/test/java/tests/api/java/lang/SystemTest.java (added)
+++ incubator/harmony/enhanced/classlib/trunk/modules/luni/src/test/java/tests/api/java/lang/SystemTest.java Wed Mar 15 03:46:17 2006
@@ -0,0 +1,343 @@
+/* Copyright 1998, 2005 The Apache Software Foundation or its licensors, as applicable
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package tests.api.java.lang;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+import java.io.PrintStream;
+import java.util.Properties;
+
+public class SystemTest extends junit.framework.TestCase {
+
+	static boolean flag = false;
+
+	static boolean ranFinalize = false;
+
+	/**
+	 * @tests java.lang.System#setIn(java.io.InputStream)
+	 */
+	public void test_setInLjava_io_InputStream() {
+		InputStream orgIn = System.in;
+		InputStream in = new ByteArrayInputStream(new byte[0]);
+		System.setIn(in);
+		assertTrue("in not set", System.in == in);
+		System.setIn(orgIn);
+	}
+
+	/**
+	 * @tests java.lang.System#setOut(java.io.PrintStream)
+	 */
+	public void test_setOutLjava_io_PrintStream() {
+		PrintStream orgOut = System.out;
+		PrintStream out = new PrintStream(new ByteArrayOutputStream());
+		System.setOut(out);
+		assertTrue("out not set", System.out == out);
+		System.setOut(orgOut);
+	}
+
+	/**
+	 * @tests java.lang.System#setErr(java.io.PrintStream)
+	 */
+	public void test_setErrLjava_io_PrintStream() {
+		PrintStream orgErr = System.err;
+		PrintStream err = new PrintStream(new ByteArrayOutputStream());
+		System.setErr(err);
+		assertTrue("err not set", System.err == err);
+		System.setErr(orgErr);
+	}
+
+	/**
+	 * @tests java.lang.System#arraycopy(java.lang.Object, int,
+	 *        java.lang.Object, int, int)
+	 */
+	public void test_arraycopyLjava_lang_ObjectILjava_lang_ObjectII() {
+		// Test for method void java.lang.System.arraycopy(java.lang.Object,
+		// int, java.lang.Object, int, int)
+		Integer a[] = new Integer[20];
+		Integer b[] = new Integer[20];
+		int i = 0;
+		while (i < a.length) {
+			a[i] = new Integer(i);
+			++i;
+		}
+		System.arraycopy(a, 0, b, 0, a.length);
+		for (i = 0; i < a.length; i++)
+			assertTrue("Copied elements incorrectly", a[i].equals(b[i]));
+
+		/* Non primitive array types don't need to be identical */
+		String[] source1 = new String[] { "element1" };
+		Object[] dest1 = new Object[1];
+		System.arraycopy(source1, 0, dest1, 0, dest1.length);
+		assertTrue("Invalid copy 1", dest1[0] == source1[0]);
+
+		char[][] source = new char[][] { { 'H', 'e', 'l', 'l', 'o' },
+				{ 'W', 'o', 'r', 'l', 'd' } };
+		char[][] dest = new char[2][];
+		System.arraycopy(source, 0, dest, 0, dest.length);
+		assertTrue("Invalid copy 2", dest[0] == source[0]
+				&& dest[1] == source[1]);
+	}
+
+	/**
+	 * @tests java.lang.System#currentTimeMillis()
+	 */
+	public void test_currentTimeMillis() {
+		// Test for method long java.lang.System.currentTimeMillis()
+		try {
+			long firstRead = System.currentTimeMillis();
+			try {
+				Thread.sleep(150);
+			} catch (InterruptedException e) {
+			}
+			long secondRead = System.currentTimeMillis();
+			assertTrue("Incorrect times returned: " + firstRead + ", "
+					+ secondRead, firstRead < secondRead);
+		} catch (Exception e) {
+			System.out.println("Exception during test: " + e.toString());
+		}
+	}
+
+	/**
+	 * @tests java.lang.System#exit(int)
+	 */
+	public void test_exitI() {
+		// Test for method void java.lang.System.exit(int)
+		// Tested in destructive test: Test_System_Exit ???
+	}
+
+	/**
+	 * @tests java.lang.System#getProperties()
+	 */
+	public void test_getProperties() {
+		// Test for method java.util.Properties java.lang.System.getProperties()
+		Properties p = System.getProperties();
+		assertTrue("Incorrect properties returned", p.getProperty(
+				"java.version").indexOf("1.", 0) >= 0);
+
+		// Ensure spec'ed properties are non-null. See System.getProperties()
+		// spec.
+		String[] props = { "java.version", "java.vendor", "java.vendor.url",
+				"java.home", "java.vm.specification.version",
+				"java.vm.specification.vendor", "java.vm.specification.name",
+				"java.vm.version", "java.vm.vendor", "java.vm.name",
+				"java.specification.name", "java.specification.vendor",
+				"java.specification.name", "java.class.version",
+				"java.class.path", "java.ext.dirs", "os.name", "os.arch",
+				"os.version", "file.separator", "path.separator",
+				"line.separator", "user.name", "user.home", "user.dir", };
+		for (int i = 0; i < props.length; i++) {
+			assertTrue(props[i], System.getProperty(props[i]) != null);
+		}
+	}
+
+	/**
+	 * @tests java.lang.System#getProperty(java.lang.String)
+	 */
+	public void test_getPropertyLjava_lang_String() {
+		// Test for method java.lang.String
+		// java.lang.System.getProperty(java.lang.String)
+		assertTrue("Failed to return correct property value", System
+				.getProperty("java.version").indexOf("1.", 0) >= 0);
+
+		boolean is8859_1 = true;
+		String encoding = System.getProperty("file.encoding");
+		byte[] bytes = new byte[128];
+		char[] chars = new char[128];
+		for (int i = 0; i < bytes.length; i++) {
+			bytes[i] = (byte) (i + 128);
+			chars[i] = (char) (i + 128);
+		}
+		String charResult = new String(bytes);
+		byte[] byteResult = new String(chars).getBytes();
+		if (charResult.length() == 128 && byteResult.length == 128) {
+			for (int i = 0; i < bytes.length; i++) {
+				if (charResult.charAt(i) != (char) (i + 128)
+						|| byteResult[i] != (byte) (i + 128))
+					is8859_1 = false;
+			}
+		} else
+			is8859_1 = false;
+		String[] possibles = new String[] { "ISO8859_1", "8859_1", "ISO8859-1",
+				"ISO-8859-1", "ISO_8859-1", "ISO_8859-1:1978", "ISO-IR-100",
+				"LATIN1", "CSISOLATIN1" };
+		boolean found8859_1 = false;
+		for (int i = 0; i < possibles.length; i++) {
+			if (possibles[i].equals(encoding)) {
+				found8859_1 = true;
+				break;
+			}
+		}
+		assertTrue("Wrong encoding: " + encoding, !is8859_1 || found8859_1);
+	}
+
+	/**
+	 * @tests java.lang.System#getProperty(java.lang.String, java.lang.String)
+	 */
+	public void test_getPropertyLjava_lang_StringLjava_lang_String() {
+		// Test for method java.lang.String
+		// java.lang.System.getProperty(java.lang.String, java.lang.String)
+		assertTrue("Failed to return correct property value: "
+				+ System.getProperty("java.version", "99999"), System
+				.getProperty("java.version", "99999").indexOf("1.", 0) >= 0);
+		assertTrue("Failed to return correct property value", System
+				.getProperty("bogus.prop", "bogus").equals("bogus"));
+	}
+
+	/**
+	 * @tests java.lang.System#setProperty(java.lang.String, java.lang.String)
+	 */
+	public void test_setPropertyLjava_lang_StringLjava_lang_String() {
+		// Test for method java.lang.String
+		// java.lang.System.setProperty(java.lang.String, java.lang.String)
+
+		assertTrue("Failed to return null", System.setProperty("testing",
+				"value1") == null);
+		assertTrue("Failed to return old value", System.setProperty("testing",
+				"value2") == "value1");
+		assertTrue("Failed to find value",
+				System.getProperty("testing") == "value2");
+
+		boolean exception = false;
+		try {
+			System.setProperty("", "default");
+		} catch (IllegalArgumentException e) {
+			exception = true;
+		}
+		assertTrue("Expected IllegalArgumentException", exception);
+	}
+
+	/**
+	 * @tests java.lang.System#getSecurityManager()
+	 */
+	public void test_getSecurityManager() {
+		// Test for method java.lang.SecurityManager
+		// java.lang.System.getSecurityManager()
+		assertTrue("Returned incorrect SecurityManager", System
+				.getSecurityManager() == null);
+	}
+
+	/**
+	 * @tests java.lang.System#identityHashCode(java.lang.Object)
+	 */
+	public void test_identityHashCodeLjava_lang_Object() {
+		// Test for method int
+		// java.lang.System.identityHashCode(java.lang.Object)
+		Object o = new Object();
+		String s = "Gabba";
+		assertTrue("Nonzero returned for null",
+				System.identityHashCode(null) == 0);
+		assertTrue("Nonequal has returned for Object", System
+				.identityHashCode(o) == o.hashCode());
+		assertTrue("Same as usual hash returned for String", System
+				.identityHashCode(s) != s.hashCode());
+	}
+
+	/**
+	 * @tests java.lang.System#runFinalization()
+	 */
+	public void test_runFinalization() {
+		// Test for method void java.lang.System.runFinalization()
+
+		flag = true;
+		createInstance();
+		int count = 10;
+		// the gc below likely bogosifies the test, but will have to do for
+		// the moment
+		while (!ranFinalize && count-- > 0) {
+			System.gc();
+			System.runFinalization();
+		}
+		assertTrue("Failed to run finalization", ranFinalize);
+	}
+
+	/**
+	 * @tests java.lang.System#runFinalizersOnExit(boolean)
+	 */
+	public void test_runFinalizersOnExitZ() {
+		// Test for method void java.lang.System.runFinalizersOnExit(boolean)
+		// Can we call the method at least?
+		try {
+			System.runFinalizersOnExit(true);
+		} catch (Throwable t) {
+			fail("Failed to set runFinalizersOnExit");
+		}
+		assertTrue("Passed runFinalizersOnExit", true);
+	}
+
+	/**
+	 * @tests java.lang.System#setProperties(java.util.Properties)
+	 */
+	public void test_setPropertiesLjava_util_Properties() {
+		// Test for method void
+		// java.lang.System.setProperties(java.util.Properties)
+
+		Properties orgProps = System.getProperties();
+		java.util.Properties tProps = new java.util.Properties();
+		tProps.put("test.prop", "this is a test property");
+		tProps.put("bogus.prop", "bogus");
+		System.setProperties(tProps);
+		try {
+			assertTrue("Failed to set properties", System.getProperties()
+					.getProperty("test.prop").equals("this is a test property"));
+		} finally {
+			// restore the original properties
+			System.setProperties(orgProps);
+		}
+	}
+
+	/**
+	 * @tests java.lang.System#setSecurityManager(java.lang.SecurityManager)
+	 */
+	public void test_setSecurityManagerLjava_lang_SecurityManager() {
+		// Test for method void
+		// java.lang.System.setSecurityManager(java.lang.SecurityManager)
+		// tested in System_Destructive ??
+	}
+
+	/**
+	 * Sets up the fixture, for example, open a network connection. This method
+	 * is called before a test is executed.
+	 */
+	protected void setUp() {
+		flag = false;
+		ranFinalize = false;
+	}
+
+	/**
+	 * Tears down the fixture, for example, close a network connection. This
+	 * method is called after a test is executed.
+	 */
+	protected void tearDown() {
+		// System.setProperties(orgProps);
+	}
+
+	protected SystemTest createInstance() {
+		return new SystemTest("FT");
+	}
+
+	protected void finalize() {
+		if (flag)
+			ranFinalize = true;
+	}
+
+	public SystemTest() {
+	}
+
+	public SystemTest(String name) {
+		super(name);
+	}
+}

Added: incubator/harmony/enhanced/classlib/trunk/modules/luni/src/test/java/tests/api/java/lang/ThreadDeathTest.java
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/classlib/trunk/modules/luni/src/test/java/tests/api/java/lang/ThreadDeathTest.java?rev=386058&view=auto
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/luni/src/test/java/tests/api/java/lang/ThreadDeathTest.java (added)
+++ incubator/harmony/enhanced/classlib/trunk/modules/luni/src/test/java/tests/api/java/lang/ThreadDeathTest.java Wed Mar 15 03:46:17 2006
@@ -0,0 +1,44 @@
+/* Copyright 1998, 2005 The Apache Software Foundation or its licensors, as applicable
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package tests.api.java.lang;
+
+public class ThreadDeathTest extends junit.framework.TestCase {
+
+	/**
+	 * @tests java.lang.ThreadDeath#ThreadDeath()
+	 */
+	public void test_Constructor() {
+		// Test for method java.lang.ThreadDeath()
+
+		ThreadDeath td = new ThreadDeath();
+
+		assertTrue(" Should be a Threaddeath", td instanceof ThreadDeath);
+	}
+
+	/**
+	 * Sets up the fixture, for example, open a network connection. This method
+	 * is called before a test is executed.
+	 */
+	protected void setUp() {
+	}
+
+	/**
+	 * Tears down the fixture, for example, close a network connection. This
+	 * method is called after a test is executed.
+	 */
+	protected void tearDown() {
+	}
+}

Added: incubator/harmony/enhanced/classlib/trunk/modules/luni/src/test/java/tests/api/java/lang/ThreadGroupTest.java
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/classlib/trunk/modules/luni/src/test/java/tests/api/java/lang/ThreadGroupTest.java?rev=386058&view=auto
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/luni/src/test/java/tests/api/java/lang/ThreadGroupTest.java (added)
+++ incubator/harmony/enhanced/classlib/trunk/modules/luni/src/test/java/tests/api/java/lang/ThreadGroupTest.java Wed Mar 15 03:46:17 2006
@@ -0,0 +1,1499 @@
+/* Copyright 1998, 2005 The Apache Software Foundation or its licensors, as applicable
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package tests.api.java.lang;
+
+import java.util.Vector;
+
+public class ThreadGroupTest extends junit.framework.TestCase {
+
+	class MyThread extends Thread {
+		public volatile int heartBeat = 0;
+
+		public MyThread(ThreadGroup group, String name)
+				throws SecurityException, IllegalThreadStateException {
+			super(group, name);
+		}
+
+		public void run() {
+			while (true) {
+				heartBeat++;
+				try {
+					Thread.sleep(50);
+				} catch (InterruptedException e) {
+				}
+			}
+		}
+
+		public boolean isActivelyRunning() {
+			long MAX_WAIT = 100;
+			return isActivelyRunning(MAX_WAIT);
+		}
+
+		public boolean isActivelyRunning(long maxWait) {
+			int beat = heartBeat;
+			long start = System.currentTimeMillis();
+			do {
+				Thread.yield();
+				int beat2 = heartBeat;
+				if (beat != beat2)
+					return true;
+			} while (System.currentTimeMillis() - start < maxWait);
+			return false;
+		}
+
+	}
+
+	private ThreadGroup rootThreadGroup = null;
+
+	private ThreadGroup initialThreadGroup = null;
+
+	/**
+	 * @tests java.lang.ThreadGroup#ThreadGroup(java.lang.String)
+	 */
+	public void test_ConstructorLjava_lang_String() {
+		// Test for method java.lang.ThreadGroup(java.lang.String)
+
+		// Unfortunately we have to use other APIs as well as we test the
+		// constructor
+
+		ThreadGroup newGroup = null;
+		ThreadGroup initial = getInitialThreadGroup();
+		final String name = "Test name";
+		newGroup = new ThreadGroup(name);
+		assertTrue(
+				"Has to be possible to create a subgroup of current group using simple constructor",
+				newGroup.getParent() == initial);
+		assertTrue("Name has to be correct", newGroup.getName().equals(name));
+
+		// cleanup
+		newGroup.destroy();
+
+	}
+
+	/**
+	 * @tests java.lang.ThreadGroup#ThreadGroup(java.lang.ThreadGroup,
+	 *        java.lang.String)
+	 */
+	public void test_ConstructorLjava_lang_ThreadGroupLjava_lang_String() {
+		// Test for method java.lang.ThreadGroup(java.lang.ThreadGroup,
+		// java.lang.String)
+
+		// Unfortunately we have to use other APIs as well as we test the
+		// constructor
+
+		ThreadGroup newGroup = null;
+
+		try {
+			newGroup = new ThreadGroup(null, null);
+		} catch (NullPointerException e) {
+		}
+		assertTrue("Can't create a ThreadGroup with a null parent",
+				newGroup == null);
+
+		newGroup = new ThreadGroup(getInitialThreadGroup(), null);
+		assertTrue("Has to be possible to create a subgroup of current group",
+				newGroup.getParent() == Thread.currentThread().getThreadGroup());
+
+		// Lets start all over
+		newGroup.destroy();
+
+		newGroup = new ThreadGroup(getRootThreadGroup(), "a name here");
+		assertTrue("Has to be possible to create a subgroup of root group",
+				newGroup.getParent() == getRootThreadGroup());
+
+		// Lets start all over
+		newGroup.destroy();
+
+		try {
+			newGroup = new ThreadGroup(newGroup, "a name here");
+		} catch (IllegalThreadStateException e) {
+			newGroup = null;
+		}
+		;
+		assertTrue("Can't create a subgroup of a destroyed group",
+				newGroup == null);
+	}
+
+	/**
+	 * @tests java.lang.ThreadGroup#activeCount()
+	 */
+	public void test_activeCount() {
+		// Test for method int java.lang.ThreadGroup.activeCount()
+		ThreadGroup tg = new ThreadGroup("activeCount");
+		Thread t1 = new Thread(tg, new Runnable() {
+			public void run() {
+				try {
+					Thread.sleep(5000);
+				} catch (InterruptedException e) {
+				}
+			}
+		});
+		int count = tg.activeCount();
+		assertTrue("wrong active count: " + count, count == 1);
+		t1.start();
+		count = tg.activeCount();
+		assertTrue("wrong active count: " + count, count == 1);
+		t1.interrupt();
+		try {
+			t1.join();
+		} catch (InterruptedException e) {
+		}
+	}
+
+	/**
+	 * @tests java.lang.ThreadGroup#checkAccess()
+	 */
+	public void test_checkAccess() {
+		// Test for method void java.lang.ThreadGroup.checkAccess()
+
+		final ThreadGroup originalCurrent = getInitialThreadGroup();
+		ThreadGroup testRoot = new ThreadGroup(originalCurrent, "Test group");
+
+		SecurityManager currentManager = System.getSecurityManager();
+		boolean passed = true;
+
+		try {
+			if (currentManager != null)
+				testRoot.checkAccess();
+		} catch (SecurityException se) {
+			passed = false;
+		}
+		;
+
+		assertTrue("CheckAccess is no-op with no Securitymanager", passed);
+
+		testRoot.destroy();
+
+	}
+
+	/**
+	 * @tests java.lang.ThreadGroup#destroy()
+	 */
+	public void test_destroy() {
+		// Test for method void java.lang.ThreadGroup.destroy()
+
+		final ThreadGroup originalCurrent = getInitialThreadGroup();
+		ThreadGroup testRoot = new ThreadGroup(originalCurrent, "Test group");
+		final int DEPTH = 4;
+		final Vector subgroups = buildRandomTreeUnder(testRoot, DEPTH);
+
+		// destroy them all
+		testRoot.destroy();
+
+		for (int i = 0; i < subgroups.size(); i++) {
+			ThreadGroup child = (ThreadGroup) subgroups.elementAt(i);
+			assertTrue("Destroyed child can't have children", child
+					.activeCount() == 0);
+			boolean passed = false;
+			try {
+				child.destroy();
+			} catch (IllegalThreadStateException e) {
+				passed = true;
+			}
+			;
+			assertTrue("Destroyed child can't be destroyed again", passed);
+		}
+
+		testRoot = new ThreadGroup(originalCurrent, "Test group (daemon)");
+		testRoot.setDaemon(true);
+
+		ThreadGroup child = new ThreadGroup(testRoot, "daemon child");
+
+		// If we destroy the last daemon's child, the daemon should get destroyed
+		// as well
+		child.destroy();
+
+		boolean passed = false;
+		try {
+			child.destroy();
+		} catch (IllegalThreadStateException e) {
+			passed = true;
+		}
+		;
+		assertTrue("Daemon should have been destroyed already", passed);
+
+		passed = false;
+		try {
+			testRoot.destroy();
+		} catch (IllegalThreadStateException e) {
+			passed = true;
+		}
+		;
+		assertTrue("Daemon parent should have been destroyed automatically",
+				passed);
+
+		assertTrue(
+				"Destroyed daemon's child should not be in daemon's list anymore",
+				!arrayIncludes(groups(testRoot), child));
+		assertTrue("Destroyed daemon should not be in parent's list anymore",
+				!arrayIncludes(groups(originalCurrent), testRoot));
+
+		testRoot = new ThreadGroup(originalCurrent, "Test group (daemon)");
+		testRoot.setDaemon(true);
+		Thread noOp = new Thread(testRoot, null, "no-op thread") {
+			public void run() {
+			}
+		};
+		noOp.start();
+
+		// Wait for the no-op thread to run inside daemon ThreadGroup
+		try {
+			noOp.join();
+		} catch (InterruptedException ie) {
+			fail("Should not be interrupted");
+		}
+		;
+
+		passed = false;
+		try {
+			child.destroy();
+		} catch (IllegalThreadStateException e) {
+			passed = true;
+		}
+		;
+		assertTrue(
+				"Daemon group should have been destroyed already when last thread died",
+				passed);
+
+		testRoot = new ThreadGroup(originalCurrent, "Test group (daemon)");
+		noOp = new Thread(testRoot, null, "no-op thread") {
+			public void run() {
+				try {
+					Thread.sleep(500);
+				} catch (InterruptedException ie) {
+					fail("Should not be interrupted");
+//					// We have our own assert
+//					myassertTrue("Should not be interrupted", false);
+				}
+				;
+			}
+		};
+
+		// Has to execute the next lines in an interval < the sleep interval of
+		// the no-op thread
+		noOp.start();
+		passed = false;
+		try {
+			testRoot.destroy();
+		} catch (IllegalThreadStateException its) {
+			passed = true;
+		}
+		assertTrue("Can't destroy a ThreadGroup that has threads", passed);
+
+		// But after the thread dies, we have to be able to destroy the thread
+		// group
+		try {
+			noOp.join();
+		} catch (InterruptedException ie) {
+			fail("Should not be interrupted");
+		}
+		;
+		passed = true;
+		try {
+			testRoot.destroy();
+		} catch (IllegalThreadStateException its) {
+			passed = false;
+		}
+		assertTrue(
+				"Should be able to destroy a ThreadGroup that has no threads",
+				passed);
+
+	}
+
+	/**
+	 * @tests java.lang.ThreadGroup#destroy()
+	 */
+	public void test_destroy_subtest0() {
+		ThreadGroup group1 = new ThreadGroup("test_destroy_subtest0");
+		group1.destroy();
+		try {
+			Thread t = new Thread(group1, "test_destroy_subtest0");
+			fail("should throw IllegalThreadStateException");
+		} catch (IllegalThreadStateException e) {
+		}
+	}
+
+	/**
+	 * @tests java.lang.ThreadGroup#getMaxPriority()
+	 */
+	public void test_getMaxPriority() {
+		// Test for method int java.lang.ThreadGroup.getMaxPriority()
+
+		final ThreadGroup originalCurrent = getInitialThreadGroup();
+		ThreadGroup testRoot = new ThreadGroup(originalCurrent, "Test group");
+
+		boolean passed = true;
+		passed = true;
+		try {
+			testRoot.setMaxPriority(Thread.MIN_PRIORITY);
+		} catch (IllegalArgumentException iae) {
+			passed = false;
+		}
+		assertTrue("Should be able to set piority", passed);
+
+		assertTrue("New value should be the same as we set", testRoot
+				.getMaxPriority() == Thread.MIN_PRIORITY);
+
+		testRoot.destroy();
+
+	}
+
+	/**
+	 * @tests java.lang.ThreadGroup#getName()
+	 */
+	public void test_getName() {
+		// Test for method java.lang.String java.lang.ThreadGroup.getName()
+
+		final ThreadGroup originalCurrent = getInitialThreadGroup();
+		final String name = "Test group";
+		final ThreadGroup testRoot = new ThreadGroup(originalCurrent, name);
+
+		assertTrue("Setting a name&getting does not work", testRoot.getName()
+				.equals(name));
+
+		testRoot.destroy();
+
+	}
+
+	static ThreadGroup checkAccessGroup = null;
+
+	/**
+	 * @tests java.lang.ThreadGroup#getParent()
+	 */
+	public void test_getParent() {
+		// Test for method java.lang.ThreadGroup
+		// java.lang.ThreadGroup.getParent()
+
+		final ThreadGroup originalCurrent = getInitialThreadGroup();
+		ThreadGroup testRoot = new ThreadGroup(originalCurrent, "Test group");
+
+		assertTrue("Parent is wrong", testRoot.getParent() == originalCurrent);
+
+		// Create some groups, nested some levels.
+		final int TOTAL_DEPTH = 5;
+		ThreadGroup current = testRoot;
+		Vector groups = new Vector();
+		// To maintain the invariant that a thread in the Vector is parent
+		// of the next one in the collection (and child of the previous one)
+		groups.addElement(testRoot);
+
+		for (int i = 0; i < TOTAL_DEPTH; i++) {
+			current = new ThreadGroup(current, "level " + i);
+			groups.addElement(current);
+		}
+
+		// Now we walk the levels down, checking if parent is ok
+		for (int i = 1; i < groups.size(); i++) {
+			current = (ThreadGroup) groups.elementAt(i);
+			ThreadGroup previous = (ThreadGroup) groups.elementAt(i - 1);
+			assertTrue("Parent is wrong", current.getParent() == previous);
+		}
+
+		SecurityManager m = new SecurityManager() {
+			public void checkAccess(ThreadGroup group) {
+				checkAccessGroup = group;
+			}
+		};
+		ThreadGroup parent;
+		try {
+			// To see if it checks Thread creation with our SecurityManager
+			System.setSecurityManager(m); 
+			parent = testRoot.getParent();
+		} finally {
+			// restore original, no side-effects
+			System.setSecurityManager(null);
+		}
+		assertTrue("checkAccess with incorrect group",
+				checkAccessGroup == parent);
+
+		testRoot.destroy();
+	}
+
+	/**
+	 * @tests java.lang.ThreadGroup#isDaemon()
+	 */
+	public void test_isDaemon() {
+		// Test for method boolean java.lang.ThreadGroup.isDaemon()
+
+		daemonTests();
+
+	}
+
+	/**
+	 * @tests java.lang.ThreadGroup#list()
+	 */
+	public void test_list() {
+		// Test for method void java.lang.ThreadGroup.list()
+
+		final ThreadGroup originalCurrent = getInitialThreadGroup();
+		// wipeSideEffectThreads destroy all side effect of threads created in
+		// java.lang.Thread
+		boolean result = wipeSideEffectThreads(originalCurrent);
+		if (result == false)
+			System.out.println("wipe threads in test_list() not successful");
+		final ThreadGroup testRoot = new ThreadGroup(originalCurrent,
+				"Test group");
+
+		// First save the original System.out
+		java.io.PrintStream originalOut = System.out;
+
+		try {
+			java.io.ByteArrayOutputStream contentsStream = new java.io.ByteArrayOutputStream(
+					100);
+			java.io.PrintStream newOut = new java.io.PrintStream(contentsStream);
+
+			// We have to "redirect" System.out to test the method 'list'
+			System.setOut(newOut);
+
+			originalCurrent.list();
+			byte[] contents = contentsStream.toByteArray();
+
+			/*
+			 * The output has to look like this
+			 * 
+			 * java.lang.ThreadGroup[name=main,maxpri=10] Thread[main,5,main]
+			 * java.lang.ThreadGroup[name=Test group,maxpri=10]
+			 * 
+			 */
+
+			boolean passed = verifyThreadList(originalCurrent, testRoot,
+					contents);
+
+			assertTrue(
+					"Either 'list' is wrong or other tests are leaving side-effects.\n"
+							+ "Result from list:\n " + "-----------------\n "
+							+ new String(contents, 0, contents.length)
+							+ "\n-----------------\n ", passed);
+
+			// Do proper cleanup
+			testRoot.destroy();
+
+		} finally {
+			// No matter what, we need to restore the original System.out
+			System.setOut(originalOut);
+		}
+
+	}
+
+	/**
+	 * @tests java.lang.ThreadGroup#parentOf(java.lang.ThreadGroup)
+	 */
+	public void test_parentOfLjava_lang_ThreadGroup() {
+		// Test for method boolean
+		// java.lang.ThreadGroup.parentOf(java.lang.ThreadGroup)
+
+		final ThreadGroup originalCurrent = getInitialThreadGroup();
+		final ThreadGroup testRoot = new ThreadGroup(originalCurrent,
+				"Test group");
+		final int DEPTH = 4;
+		buildRandomTreeUnder(testRoot, DEPTH);
+
+		final ThreadGroup[] allChildren = allGroups(testRoot);
+		for (int i = 0; i < allChildren.length; i++) {
+			assertTrue("Have to be parentOf all children", testRoot
+					.parentOf((ThreadGroup) allChildren[i]));
+		}
+
+		assertTrue("Have to be parentOf itself", testRoot.parentOf(testRoot));
+
+		testRoot.destroy();
+		assertTrue("Parent can't have test group as subgroup anymore",
+				!arrayIncludes(groups(testRoot.getParent()), testRoot));
+
+		try {
+			System.setSecurityManager(new SecurityManager());
+			assertTrue("Should not be parent", !testRoot
+					.parentOf(originalCurrent));
+		} finally {
+			System.setSecurityManager(null);
+		}
+	}
+
+	/**
+	 * @tests java.lang.ThreadGroup#resume()
+	 */
+	public void test_resume() throws OutOfMemoryError {
+		// Test for method void java.lang.ThreadGroup.resume()
+
+		final ThreadGroup originalCurrent = getInitialThreadGroup();
+
+		final ThreadGroup testRoot = new ThreadGroup(originalCurrent,
+				"Test group");
+		final int DEPTH = 2;
+		buildRandomTreeUnder(testRoot, DEPTH);
+
+		final int THREADS_PER_GROUP = 2;
+		final Vector threads = populateGroupsWithThreads(testRoot,
+				THREADS_PER_GROUP);
+
+		assertTrue("Internal error when populating ThreadGroups", testRoot
+				.activeCount() == threads.size());
+
+		boolean[] isResumed = null;
+		try {
+			try {
+				for (int i = 0; i < threads.size(); i++) {
+					Thread t = (Thread) threads.elementAt(i);
+					t.start();
+					t.suspend();
+				}
+			} catch (OutOfMemoryError e) {
+				for (int i = 0; i < threads.size(); i++) {
+					Thread t = (Thread) threads.elementAt(i);
+					t.resume();
+					t.stop(); // deprecated but effective
+				}
+				throw e;
+			}
+
+			// Now that they are all suspended, let's resume the ThreadGroup
+			testRoot.resume();
+
+			// Give them some time to really resume
+			try {
+				Thread.sleep(1000);
+			} catch (InterruptedException ie) {
+				fail("Should not have been interrupted");
+			}
+
+			isResumed = new boolean[threads.size()];
+			boolean failed = false;
+			for (int i = 0; i < isResumed.length; i++) {
+				MyThread t = (MyThread) threads.elementAt(i);
+				if (!failed) { // if one failed, don't waste time checking the
+					// rest
+					isResumed[i] = t.isActivelyRunning(5000);
+					failed = failed | (!isResumed[i]);
+				}
+				t.stop(); // deprecated but effective
+			}
+
+			// Give them some time to really die
+			try {
+				Thread.sleep(1000);
+			} catch (InterruptedException ie) {
+				fail("Should not have been interrupted");
+			}
+		} finally {
+			// Make sure we do cleanup before returning
+			testRoot.destroy();
+		}
+
+		for (int i = 0; i < isResumed.length; i++) {
+			assertTrue("Thread " + threads.elementAt(i)
+					+ " was not running when it was killed", isResumed[i]);
+		}
+
+		assertTrue("Method destroy must have problems",
+				testRoot.activeCount() == 0);
+
+	}
+
+	/**
+	 * @tests java.lang.ThreadGroup#setDaemon(boolean)
+	 */
+	public void test_setDaemonZ() {
+		// Test for method void java.lang.ThreadGroup.setDaemon(boolean)
+
+		daemonTests();
+
+	}
+
+	/**
+	 * @tests java.lang.ThreadGroup#setMaxPriority(int)
+	 */
+	public void test_setMaxPriorityI() {
+		// Test for method void java.lang.ThreadGroup.setMaxPriority(int)
+
+		final ThreadGroup originalCurrent = getInitialThreadGroup();
+		ThreadGroup testRoot = new ThreadGroup(originalCurrent, "Test group");
+
+		boolean passed;
+
+		// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+		int currentMax = testRoot.getMaxPriority();
+		testRoot.setMaxPriority(Thread.MAX_PRIORITY + 1);
+		passed = testRoot.getMaxPriority() == currentMax;
+		assertTrue(
+				"setMaxPriority: Any value higher than the current one is ignored. Before: "
+						+ currentMax + " , after: " + testRoot.getMaxPriority(),
+				passed);
+
+		// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+		currentMax = testRoot.getMaxPriority();
+		testRoot.setMaxPriority(Thread.MIN_PRIORITY - 1);
+		passed = testRoot.getMaxPriority() == Thread.MIN_PRIORITY;
+		assertTrue(
+				"setMaxPriority: Any value smaller than MIN_PRIORITY is adjusted to MIN_PRIORITY. Before: "
+						+ currentMax + " , after: " + testRoot.getMaxPriority(),
+				passed);
+
+		// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+		testRoot.destroy();
+		testRoot = new ThreadGroup(originalCurrent, "Test group");
+
+		// Create some groups, nested some levels. Each level will have maxPrio
+		// 1 unit smaller than the parent's. However, there can't be a group
+		// with priority < Thread.MIN_PRIORITY
+		final int TOTAL_DEPTH = testRoot.getMaxPriority() - Thread.MIN_PRIORITY
+				- 2;
+		ThreadGroup current = testRoot;
+		for (int i = 0; i < TOTAL_DEPTH; i++) {
+			current = new ThreadGroup(current, "level " + i);
+		}
+
+		// Now we walk the levels down, changing the maxPrio and later verifying
+		// that the value is indeed 1 unit smaller than the parent's maxPrio.
+		int maxPrio, parentMaxPrio;
+		current = testRoot;
+
+		// To maintain the invariant that when we are to modify a child,
+		// its maxPriority is always 1 unit smaller than its parent's.
+		// We have to set it for the root manually, and the loop does the rest
+		// for all the other sub-levels
+		current.setMaxPriority(current.getParent().getMaxPriority() - 1);
+
+		for (int i = 0; i < TOTAL_DEPTH; i++) {
+			maxPrio = current.getMaxPriority();
+			parentMaxPrio = current.getParent().getMaxPriority();
+
+			ThreadGroup[] children = groups(current);
+			assertTrue("Can only have 1 subgroup", children.length == 1);
+			current = children[0];
+			assertTrue(
+					"Had to be 1 unit smaller than parent's priority in iteration="
+							+ i + " checking->" + current,
+					maxPrio == parentMaxPrio - 1);
+			current.setMaxPriority(maxPrio - 1);
+
+			// The next test is sort of redundant, since in next iteration it
+			// will be the parent tGroup, so the test will be done.
+			assertTrue("Had to be possible to change max priority", current
+					.getMaxPriority() == maxPrio - 1);
+		}
+
+		assertTrue(
+				"Priority of leaf child group has to be much smaller than original root group",
+				current.getMaxPriority() == testRoot.getMaxPriority()
+						- TOTAL_DEPTH);
+
+		testRoot.destroy();
+
+		// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+		passed = true;
+		testRoot = new ThreadGroup(originalCurrent, "Test group");
+		try {
+			testRoot.setMaxPriority(Thread.MAX_PRIORITY);
+		} catch (IllegalArgumentException iae) {
+			passed = false;
+		}
+		assertTrue(
+				"Max Priority = Thread.MAX_PRIORITY should be possible if the test is run with default system ThreadGroup as root",
+				passed);
+		testRoot.destroy();
+
+		// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+
+		passed = true;
+		testRoot = new ThreadGroup(originalCurrent, "Test group");
+		System.setSecurityManager(new SecurityManager());
+		try {
+			try {
+				testRoot.setMaxPriority(Thread.MIN_PRIORITY);
+			} catch (IllegalArgumentException iae) {
+				passed = false;
+			}
+		} finally {
+			System.setSecurityManager(null);
+		}
+		assertTrue(
+				"Min Priority = Thread.MIN_PRIORITY should be possible, always",
+				passed);
+		testRoot.destroy();
+
+		try {
+			System.setSecurityManager(new SecurityManager());
+			originalCurrent.setMaxPriority(Thread.MAX_PRIORITY);
+		} finally {
+			System.setSecurityManager(null);
+		}
+	}
+
+	/**
+	 * @tests java.lang.ThreadGroup#stop()
+	 */
+	public void test_stop() throws OutOfMemoryError {
+		// Test for method void java.lang.ThreadGroup.stop()
+
+		final ThreadGroup originalCurrent = getInitialThreadGroup();
+
+		final ThreadGroup testRoot = new ThreadGroup(originalCurrent,
+				"Test group");
+		final int DEPTH = 2;
+		buildRandomTreeUnder(testRoot, DEPTH);
+
+		final int THREADS_PER_GROUP = 2;
+		final Vector threads = populateGroupsWithThreads(testRoot,
+				THREADS_PER_GROUP);
+
+		try {
+			for (int i = 0; i < threads.size(); i++) {
+				Thread t = (Thread) threads.elementAt(i);
+				t.start();
+			}
+		} catch (OutOfMemoryError e) {
+			for (int i = 0; i < threads.size(); i++) {
+				Thread t = (Thread) threads.elementAt(i);
+				t.stop(); // deprecated but effective
+			}
+			throw e;
+		}
+
+		// Now that they are all running, let's stop the ThreadGroup
+		testRoot.stop();
+
+		// stop is an async call. The thread may take a while to stop. We have
+		// to wait for all of them to stop. However, if stop does not work,
+		// we'd have to wait forever. So, we wait with a timeout, and if the
+		// Thread is still alive, we assume stop for ThreadGroups does not
+		// work. How much we wait (timeout) is very important
+		boolean passed = true;
+		for (int i = 0; i < threads.size(); i++) {
+			Thread t = (Thread) threads.elementAt(i);
+			try {
+				// We wait 5000 ms per Thread, but due to scheduling it may
+				// take a while to run
+				t.join(5000);
+			} catch (InterruptedException ie) {
+				fail("Should not be interrupted");
+			}
+			if (t.isAlive()) {
+				passed = false;
+				break;
+			}
+		}
+
+		// To make sure that even if we fail, we exit in a clean state
+		testRoot.destroy();
+
+		assertTrue("Thread should be dead by now", passed);
+
+		assertTrue("Method destroy (or wipeAllThreads) must have problems",
+				testRoot.activeCount() == 0);
+
+	}
+
+	/**
+	 * @tests java.lang.ThreadGroup#suspend()
+	 */
+	public void test_suspend() throws OutOfMemoryError {
+		// Test for method void java.lang.ThreadGroup.suspend()
+
+		final ThreadGroup originalCurrent = getInitialThreadGroup();
+
+		final ThreadGroup testRoot = new ThreadGroup(originalCurrent,
+				"Test group");
+		final int DEPTH = 2;
+		buildRandomTreeUnder(testRoot, DEPTH);
+
+		final int THREADS_PER_GROUP = 2;
+		final Vector threads = populateGroupsWithThreads(testRoot,
+				THREADS_PER_GROUP);
+
+		boolean passed = false;
+		try {
+			try {
+				for (int i = 0; i < threads.size(); i++) {
+					Thread t = (Thread) threads.elementAt(i);
+					t.start();
+				}
+			} catch (OutOfMemoryError e) {
+				for (int i = 0; i < threads.size(); i++) {
+					Thread t = (Thread) threads.elementAt(i);
+					t.stop(); // deprecated but effective
+				}
+				throw e;
+			}
+
+			// Now that they are all running, let's suspend the ThreadGroup
+			testRoot.suspend();
+
+			passed = allSuspended(threads);
+			assertTrue("Should be able to wipe all threads (allSuspended="
+					+ passed + ")", wipeAllThreads(testRoot));
+		} finally {
+
+			// We can't destroy a ThreadGroup if we do not make sure it has no
+			// threads at all
+
+			// Make sure we cleanup before returning from the method
+			testRoot.destroy();
+		}
+		assertTrue("All threads should be suspended", passed);
+
+		assertTrue("Method destroy (or wipeAllThreads) must have problems",
+				testRoot.activeCount() == 0);
+
+	}
+
+	/**
+	 * @tests java.lang.ThreadGroup#toString()
+	 */
+	public void test_toString() {
+		// Test for method java.lang.String java.lang.ThreadGroup.toString()
+
+		final ThreadGroup originalCurrent = getInitialThreadGroup();
+		final String tGroupName = "Test group";
+
+		// Our own subclass
+		class MyThreadGroup extends ThreadGroup {
+			// Have to define a constructor since there's no default one
+			public MyThreadGroup(ThreadGroup parent, String name) {
+				super(parent, name);
+			}
+		}
+		;
+
+		ThreadGroup testRoot = new MyThreadGroup(originalCurrent, tGroupName);
+		final String toString = testRoot.toString();
+
+		StringBuffer expectedResult = new StringBuffer();
+		expectedResult.append(testRoot.getClass().getName());
+		expectedResult.append("[name=");
+		expectedResult.append(tGroupName);
+		expectedResult.append(",maxpri=");
+		expectedResult.append(testRoot.getMaxPriority());
+		expectedResult.append("]");
+
+		String expectedValue = expectedResult.toString();
+
+		assertTrue("toString does not follow the Java language spec.", toString
+				.equals(expectedValue));
+
+		testRoot.destroy();
+	}
+
+	/**
+	 * @tests java.lang.ThreadGroup#uncaughtException(java.lang.Thread,
+	 *        java.lang.Throwable)
+	 */
+	public void test_uncaughtExceptionLjava_lang_ThreadLjava_lang_Throwable() {
+		// Test for method void
+		// java.lang.ThreadGroup.uncaughtException(java.lang.Thread,
+		// java.lang.Throwable)
+
+		final ThreadGroup originalCurrent = getInitialThreadGroup();
+
+		// indices for the array defined below
+		final int TEST_DEATH = 0;
+		final int TEST_OTHER = 1;
+		final int TEST_EXCEPTION_IN_UNCAUGHT = 2;
+		final int TEST_OTHER_THEN_DEATH = 3;
+		final int TEST_FORCING_THROW_THREAD_DEATH = 4;
+		final int TEST_KILLING = 5;
+		final int TEST_DEATH_AFTER_UNCAUGHT = 6;
+
+		final boolean[] passed = new boolean[] { false, false, false, false,
+				false, false, false };
+
+		ThreadGroup testRoot;
+		Thread thread;
+
+		// Our own exception class
+		class TestException extends RuntimeException {
+		}
+		;
+
+		// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+		// - - - - - - -
+		testRoot = new ThreadGroup(originalCurrent,
+				"Test killing a Thread, forcing it to throw ThreadDeath") {
+			public void uncaughtException(Thread t, Throwable e) {
+				if (e instanceof ThreadDeath)
+					passed[TEST_KILLING] = true;
+				// always forward, any exception
+				super.uncaughtException(t, e);
+			}
+		};
+
+		// Test if a Thread tells its ThreadGroup about ThreadDeath
+		thread = new Thread(testRoot, null, "victim thread (to be killed)") {
+			public void run() {
+				while (true) {
+					Thread.yield();
+				}
+			}
+		};
+		thread.start();
+		try {
+			Thread.sleep(1000);
+		} catch (InterruptedException ie) {
+			fail("Should not have been interrupted");
+		}
+		// we know this is deprecated, but we must test this scenario.
+		// When we stop a thread, it is tagged as not alive even though it is
+		// still running code.
+		// join would be a no-op, and we might have a race condition. So, to
+		// play safe, we wait before joining & testing if the exception was
+		// really forwarded to the ThreadGroup
+		thread.stop();
+		try {
+			Thread.sleep(1000);
+		} catch (InterruptedException ie) {
+			fail("Should not have been interrupted");
+		}
+		try {
+			thread.join();
+		} catch (InterruptedException ie) {
+			fail("Should not have been interrupted");
+		}
+		testRoot.destroy();
+		assertTrue(
+				"Any thread should notify its ThreadGroup about its own death, even if killed:"
+						+ testRoot, passed[TEST_KILLING]);
+
+		// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+		// - - - - - - -
+		testRoot = new ThreadGroup(originalCurrent,
+				"Test Forcing a throw of ThreadDeath") {
+			public void uncaughtException(Thread t, Throwable e) {
+				if (e instanceof ThreadDeath)
+					passed[TEST_FORCING_THROW_THREAD_DEATH] = true;
+				// always forward, any exception
+				super.uncaughtException(t, e);
+			}
+		};
+
+		// Test if a Thread tells its ThreadGroup about ThreadDeath
+		thread = new Thread(testRoot, null, "suicidal thread") {
+			public void run() {
+				throw new ThreadDeath();
+			}
+		};
+		thread.start();
+		try {
+			thread.join();
+		} catch (InterruptedException ie) {
+			fail("Should not have been interrupted");
+		}
+		testRoot.destroy();
+		assertTrue(
+				"Any thread should notify its ThreadGroup about its own death, even if suicide:"
+						+ testRoot, passed[TEST_FORCING_THROW_THREAD_DEATH]);
+
+		// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+		// - - - - - - -
+
+		testRoot = new ThreadGroup(originalCurrent, "Test ThreadDeath") {
+			public void uncaughtException(Thread t, Throwable e) {
+				passed[TEST_DEATH] = false;
+				// always forward, any exception
+				super.uncaughtException(t, e);
+			}
+		};
+
+		// Test if a Thread tells its ThreadGroup about ThreadDeath
+		passed[TEST_DEATH] = true;
+		thread = new Thread(testRoot, null, "no-op thread");
+		thread.start();
+		try {
+			thread.join();
+		} catch (InterruptedException ie) {
+			fail("Should not have been interrupted");
+		}
+		testRoot.destroy();
+		assertTrue("A thread should not call uncaughtException when it dies:"
+				+ testRoot, passed[TEST_DEATH]);
+
+		// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+		// - - - - - - -
+
+		testRoot = new ThreadGroup(originalCurrent, "Test other Exception") {
+			public void uncaughtException(Thread t, Throwable e) {
+				if (e instanceof TestException)
+					passed[TEST_OTHER] = true;
+				else
+					// only forward exceptions other than our test
+					super.uncaughtException(t, e);
+			}
+		};
+
+		// Test if a Thread tells its ThreadGroup about an Exception
+		thread = new Thread(testRoot, null, "no-op thread") {
+			public void run() {
+				throw new TestException();
+			}
+		};
+		thread.start();
+		try {
+			thread.join();
+		} catch (InterruptedException ie) {
+			fail("Should not have been interrupted");
+		}
+		testRoot.destroy();
+		assertTrue(
+				"Any thread should notify its ThreadGroup about an uncaught exception:"
+						+ testRoot, passed[TEST_OTHER]);
+
+		// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+		// - - - - - - -
+
+		// Our own uncaught exception class
+		class UncaughtException extends TestException {
+		}
+		;
+
+		testRoot = new ThreadGroup(originalCurrent,
+				"Test Exception in uncaught exception") {
+			public void uncaughtException(Thread t, Throwable e) {
+				if (e instanceof TestException) {
+					passed[TEST_EXCEPTION_IN_UNCAUGHT] = true;
+					// Let's simulate an error inside our uncaughtException
+					// method.
+					// This should be no-op according to the spec
+					throw new UncaughtException();
+				} else
+					// only forward exceptions other than our test
+					super.uncaughtException(t, e);
+			}
+		};
+
+		// Test if an Exception in uncaughtException is really a no-op
+		thread = new Thread(testRoot, null, "no-op thread") {
+			public void run() {
+				try {
+					throw new TestException();
+				} catch (UncaughtException ue) {
+					// any exception in my ThreadGroup's uncaughtException must
+					// not be propagated.
+					// If it gets propagated and we detected that, the test failed
+					passed[TEST_EXCEPTION_IN_UNCAUGHT] = false;
+				}
+			}
+		};
+		thread.start();
+		try {
+			thread.join();
+		} catch (InterruptedException ie) {
+			fail("Should not have been interrupted");
+		}
+		testRoot.destroy();
+		assertTrue(
+				"Any uncaughtException in uncaughtException should be no-op:"
+						+ testRoot, passed[TEST_EXCEPTION_IN_UNCAUGHT]);
+
+		// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+		// - - - - - - -
+
+		// This is a mix of 2 of the tests above. It is assumed that ThreadDeath
+		// and any random exception do work , tested separately. Now we test
+		// if after an uncaughtException is forwarded to the ThreadGroup and
+		// the Thread dies, if ThreadDeath is also forwarded. It should be
+		// (so that a ThreadGroup can know its Thread died)
+		testRoot = new ThreadGroup(originalCurrent,
+				"Test Uncaught followed by ThreadDeath") {
+			public void uncaughtException(Thread t, Throwable e) {
+				if (e instanceof ThreadDeath)
+					passed[TEST_DEATH_AFTER_UNCAUGHT] = true;
+				if (e instanceof TestException)
+					passed[TEST_OTHER_THEN_DEATH] = true;
+				else
+					// only forward exceptions other than our test
+					super.uncaughtException(t, e);
+			}
+		};
+
+		// Test if a Thread tells its ThreadGroup about an Exception and also
+		// ThreadDeath
+		thread = new Thread(testRoot, null, "no-op thread") {
+			public void run() {
+				throw new TestException();
+			}
+		};
+		thread.start();
+		try {
+			thread.join();
+		} catch (InterruptedException ie) {
+			fail("Should not have been interrupted");
+		}
+		testRoot.destroy();
+	}
+
+	/**
+	 * Sets up the fixture, for example, open a network connection. This method
+	 * is called before a test is executed.
+	 */
+	protected void setUp() {
+		initialThreadGroup = Thread.currentThread().getThreadGroup();
+		rootThreadGroup = initialThreadGroup;
+		while (rootThreadGroup.getParent() != null)
+			rootThreadGroup = rootThreadGroup.getParent();
+	}
+
+	/**
+	 * Tears down the fixture, for example, close a network connection. This
+	 * method is called after a test is executed.
+	 */
+	protected void tearDown() {
+		try {
+			// Give the threads a chance to die.
+			Thread.sleep(50);
+		} catch (InterruptedException e) {
+		}
+	}
+
+	private Thread[] threads(ThreadGroup parent) {
+		// No API to get the count of immediate children only ?
+		int count = parent.activeCount();
+		Thread[] all = new Thread[count];
+		int actualSize = parent.enumerate(all, false);
+		Thread[] result;
+		if (actualSize == all.length)
+			result = all;
+		else {
+			result = new Thread[actualSize];
+			System.arraycopy(all, 0, result, 0, actualSize);
+		}
+
+		return result;
+
+	}
+
+	private ThreadGroup getInitialThreadGroup() {
+		return initialThreadGroup;
+	}
+
+	private ThreadGroup[] allGroups(ThreadGroup parent) {
+		int count = parent.activeGroupCount();
+		ThreadGroup[] all = new ThreadGroup[count];
+		parent.enumerate(all, true);
+		return all;
+	}
+
+	private void daemonTests() {
+		// Test for method void java.lang.ThreadGroup.setDaemon(boolean)
+
+		final ThreadGroup originalCurrent = getInitialThreadGroup();
+		final ThreadGroup testRoot = new ThreadGroup(originalCurrent,
+				"Test group");
+
+		testRoot.setDaemon(true);
+		assertTrue("Setting daemon&getting does not work", testRoot.isDaemon());
+
+		testRoot.setDaemon(false);
+		assertTrue("Setting daemon&getting does not work", !testRoot.isDaemon());
+
+		testRoot.destroy();
+
+	}
+
+	private boolean wipeAllThreads(final ThreadGroup aGroup) {
+		boolean ok = true;
+		Thread[] threads = threads(aGroup);
+		for (int i = 0; i < threads.length; i++) {
+			Thread t = threads[i];
+			ok = ok && wipeThread(t);
+		}
+
+		// Recursively for subgroups (if any)
+		ThreadGroup[] children = groups(aGroup);
+		for (int i = 0; i < children.length; i++) {
+			ok = ok && wipeAllThreads(children[i]);
+		}
+
+		return ok;
+
+	}
+
+	private boolean wipeAllThreads(final Vector threads) {
+		boolean ok = true;
+		for (int i = 0; i < threads.size(); i++) {
+			Thread t = (Thread) threads.elementAt(i);
+			ok = ok && wipeThread(t);
+		}
+
+		return ok;
+
+	}
+
+	private boolean wipeSideEffectThreads(ThreadGroup aGroup) {
+		boolean ok = true;
+		Thread[] threads = threads(aGroup);
+		for (int i = 0; i < threads.length; i++) {
+			Thread t = threads[i];
+			if (t.getName().equals("SimpleThread")
+					|| t.getName().equals("Bogus Name")
+					|| t.getName().equals("Testing")
+					|| t.getName().equals("foo")
+					|| t.getName().equals("Test Group")
+					|| t.getName().equals("Squawk")
+					|| t.getName().equals("Thread-1")
+					|| t.getName().equals("firstOne")
+					|| t.getName().equals("secondOne")
+					|| t.getName().equals("Thread-16")
+					|| t.getName().equals("Thread-14"))
+				ok = ok && wipeThread(t);
+		}
+
+		// Recursively for subgroups (if any)
+		ThreadGroup[] children = groups(aGroup);
+
+		for (int i = 0; i < children.length; i++) {
+			ok = ok && wipeSideEffectThreads(children[i]);
+			if (children[i].getName().equals("Test Group")
+					|| children[i].getName().equals("foo")
+					|| children[i].getName().equals("jp"))
+				children[i].destroy();
+		}
+		try {
+			// Give the threads a chance to die.
+			Thread.sleep(50);
+		} catch (InterruptedException e) {
+		}
+		return ok;
+	}
+
+	private void asyncBuildRandomTreeUnder(final ThreadGroup aGroup,
+			final int depth, final Vector allCreated) {
+		if (depth <= 0)
+			return;
+
+		final int maxImmediateSubgroups = random(3);
+		for (int i = 0; i < maxImmediateSubgroups; i++) {
+			final int iClone = i;
+			final String name = " Depth = " + depth + ",N = " + iClone
+					+ ",Vector size at creation: " + allCreated.size();
+			// Use concurrency to maximize chance of exposing concurrency bugs
+			// in ThreadGroups
+			Thread t = new Thread(aGroup, name) {
+				public void run() {
+					ThreadGroup newGroup = new ThreadGroup(aGroup, name);
+					allCreated.addElement(newGroup);
+					asyncBuildRandomTreeUnder(newGroup, depth - 1, allCreated);
+				}
+			};
+			t.start();
+		}
+
+	}
+
+	private Vector asyncBuildRandomTreeUnder(final ThreadGroup aGroup,
+			final int depth) {
+		Vector result = new Vector();
+		asyncBuildRandomTreeUnder(aGroup, depth, result);
+		return result;
+
+	}
+
+	private boolean verifyThreadList(ThreadGroup root,
+			ThreadGroup onlyChildGroup, byte[] listOutput) {
+		// We expect that @root has only 1 subgroup, @onlyChildGroup. The
+		// output from  method 'list' is stored in @listOutput
+		if (listOutput.length == 0) {
+			return false;
+		}
+
+		// If we got a long output, it means some previous test must have left
+		// side-effects (more subgroups and threads);
+		final int MAX_SIZE = 200;
+		if (listOutput.length > MAX_SIZE) {
+			return false;
+		}
+
+		// Here we compare actual result to expected result
+
+		// Due to extremely weak API in String, comparing substrings, etc would
+		// take too much work at this time.
+		// We defer the actual implementation for now.
+		return true;
+	}
+
+	private boolean allNotSuspended(Vector threads) {
+		for (int i = 0; i < threads.size(); i++) {
+			MyThread t = (MyThread) threads.elementAt(i);
+			if (!t.isActivelyRunning())
+				return false;
+		}
+
+		return true;
+
+	}
+
+	private boolean allSuspended(Vector threads) {
+		for (int i = 0; i < threads.size(); i++) {
+			MyThread t = (MyThread) threads.elementAt(i);
+			if (t.isActivelyRunning())
+				return false;
+		}
+
+		return true;
+
+	}
+
+	private boolean sameThreads(Thread[] allThreads, Vector threads) {
+		if (allThreads.length != threads.size())
+			return false;
+
+		// The complexity of this method is N2, and we do it twice !!
+
+		// First make sure that all threads in @threads are also in @allThreads
+		for (int i = 0; i < allThreads.length; i++) {
+			Thread t = (Thread) threads.elementAt(i);
+			if (!arrayIncludes(allThreads, t))
+				return false;
+		}
+
+		// Now make sure that all threads in @allThreads are also in @threads
+		Thread[] vectorThreads = new Thread[threads.size()];
+		threads.copyInto(vectorThreads);
+		for (int i = 0; i < vectorThreads.length; i++) {
+			Thread t = allThreads[i];
+			if (!arrayIncludes(vectorThreads, t))
+				return false;
+		}
+
+		return true;
+
+	}
+
+	private ThreadGroup[] groups(ThreadGroup parent) {
+		// No API to get the count of immediate children only ?
+		int count = parent.activeGroupCount();
+		ThreadGroup[] all = new ThreadGroup[count];
+		parent.enumerate(all, false);
+		// Now we may have nulls in the array, we must find the actual size
+		int actualSize = 0;
+		for (; actualSize < all.length; actualSize++) {
+			if (all[actualSize] == null)
+				break;
+		}
+		ThreadGroup[] result;
+		if (actualSize == all.length)
+			result = all;
+		else {
+			result = new ThreadGroup[actualSize];
+			System.arraycopy(all, 0, result, 0, actualSize);
+		}
+
+		return result;
+
+	}
+
+	private Vector populateGroupsWithThreads(final ThreadGroup aGroup,
+			final int threadCount) {
+		Vector result = new Vector();
+		populateGroupsWithThreads(aGroup, threadCount, result);
+		return result;
+
+	}
+
+	private void populateGroupsWithThreads(final ThreadGroup aGroup,
+			final int threadCount, final Vector allCreated) {
+		for (int i = 0; i < threadCount; i++) {
+			final int iClone = i;
+			final String name = "(MyThread)N =" + iClone + "/" + threadCount
+					+ " ,Vector size at creation: " + allCreated.size();
+
+			MyThread t = new MyThread(aGroup, name);
+			allCreated.addElement(t);
+		}
+
+		// Recursively for subgroups (if any)
+		ThreadGroup[] children = groups(aGroup);
+		for (int i = 0; i < children.length; i++) {
+			populateGroupsWithThreads(children[i], threadCount, allCreated);
+		}
+
+	}
+
+	private int random(int max) {
+
+		return 1 + ((new Object()).hashCode() % max);
+
+	}
+
+	private boolean parentOfAll(ThreadGroup parentCandidate,
+			ThreadGroup[] childrenCandidates) {
+		for (int i = 0; i < childrenCandidates.length; i++) {
+			if (!parentCandidate.parentOf(childrenCandidates[i]))
+				return false;
+		}
+
+		return true;
+
+	}
+
+	private boolean wipeThread(Thread t) {
+		t.stop();
+		try {
+			t.join(1000);
+		} catch (InterruptedException ie) {
+			fail("Should not have been interrupted");
+		}
+		// The thread had plenty (subjective) of time to die so there 
+		// is a problem.
+		if (t.isAlive())
+			return false;
+
+		return true;
+	}
+
+	private Vector buildRandomTreeUnder(ThreadGroup aGroup, int depth) {
+		Vector result = asyncBuildRandomTreeUnder(aGroup, depth);
+		while (true) {
+			int sizeBefore = result.size();
+			try {
+				Thread.sleep(1000);
+				int sizeAfter = result.size();
+				// If no activity for a while, we assume async building may be
+				// done.
+				if (sizeBefore == sizeAfter)
+					// It can only be done if no more threads. Unfortunately we
+					// are relying on this API to work as well.
+					// If it does not, we may loop forever.
+					if (aGroup.activeCount() == 0)
+						break;
+			} catch (InterruptedException e) {
+			}
+		}
+		return result;
+
+	}
+
+	private boolean arrayIncludes(Object[] array, Object toTest) {
+		for (int i = 0; i < array.length; i++) {
+			if (array[i] == toTest)
+				return true;
+		}
+
+		return false;
+	}
+
+	protected void myassertTrue(String msg, boolean b) {
+		// This method is defined here just to solve a visibility problem
+		// of protected methods with inner types
+		this.assertTrue(msg, b);
+	}
+
+	private ThreadGroup getRootThreadGroup() {
+		return rootThreadGroup;
+
+	}
+}

Added: incubator/harmony/enhanced/classlib/trunk/modules/luni/src/test/java/tests/api/java/lang/ThreadLocalTest.java
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/classlib/trunk/modules/luni/src/test/java/tests/api/java/lang/ThreadLocalTest.java?rev=386058&view=auto
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/luni/src/test/java/tests/api/java/lang/ThreadLocalTest.java (added)
+++ incubator/harmony/enhanced/classlib/trunk/modules/luni/src/test/java/tests/api/java/lang/ThreadLocalTest.java Wed Mar 15 03:46:17 2006
@@ -0,0 +1,133 @@
+/* Copyright 1998, 2005 The Apache Software Foundation or its licensors, as applicable
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package tests.api.java.lang;
+
+public class ThreadLocalTest extends junit.framework.TestCase {
+
+	/**
+	 * @tests java.lang.ThreadLocal#ThreadLocal()
+	 */
+	public void test_Constructor() {
+		// Test for method java.lang.ThreadLocal()
+
+		ThreadLocal l = new ThreadLocal();
+		assertTrue("Failed to create ThreadLocal", l instanceof ThreadLocal);
+
+	}
+
+	/**
+	 * @tests java.lang.ThreadLocal#get()
+	 */
+	public void test_get() {
+		// Test for method java.lang.Object java.lang.ThreadLocal.get()
+		ThreadLocal l = new ThreadLocal();
+		assertTrue("ThreadLocal's initial value is null", l.get() == null);
+
+		// The ThreadLocal has to run once for each thread that touches the
+		// ThreadLocal
+		final Object INITIAL_VALUE = "'foo'";
+		final ThreadLocal l1 = new ThreadLocal() {
+			protected Object initialValue() {
+				return INITIAL_VALUE;
+			}
+		};
+
+		assertTrue("ThreadLocal's initial value should be " + INITIAL_VALUE
+				+ " but is " + l1.get(), l1.get() == INITIAL_VALUE);
+
+		// We need this because inner types cannot assign to variables in
+		// container method. But assigning to object slots in the container
+		// method is ok.
+		class ResultSlot {
+			public Object result = null;
+		}
+
+		final ResultSlot THREADVALUE = new ResultSlot();
+		Thread t = new Thread() {
+			public void run() {
+				THREADVALUE.result = l1.get();
+			}
+		};
+
+		// Wait for the other Thread assign what it observes as the value of the
+		// variable
+		t.start();
+		try {
+			t.join();
+		} catch (InterruptedException ie) {
+			fail("Interrupted!!");
+		}
+
+		assertTrue("ThreadLocal's initial value in other Thread should be "
+				+ INITIAL_VALUE, THREADVALUE.result == INITIAL_VALUE);
+
+	}
+
+	/**
+	 * @tests java.lang.ThreadLocal#set(java.lang.Object)
+	 */
+	public void test_setLjava_lang_Object() {
+		// Test for method void java.lang.ThreadLocal.set(java.lang.Object)
+
+		final Object OBJ = new Object();
+		final ThreadLocal l = new ThreadLocal();
+		l.set(OBJ);
+		assertTrue("ThreadLocal's initial value is " + OBJ, l.get() == OBJ);
+
+		// We need this because inner types cannot assign to variables in
+		// container method.
+		// But assigning to object slots in the container method is ok.
+		class ResultSlot {
+			public Object result = null;
+		}
+
+		final ResultSlot THREADVALUE = new ResultSlot();
+		Thread t = new Thread() {
+			public void run() {
+				THREADVALUE.result = l.get();
+			}
+		};
+
+		// Wait for the other Thread assign what it observes as the value of the
+		// variable
+		t.start();
+		try {
+			t.join();
+		} catch (InterruptedException ie) {
+			fail("Interrupted!!");
+		}
+
+		// ThreadLocal is not inherited, so the other Thread should see it as
+		// null
+		assertTrue("ThreadLocal's value in other Thread should be null",
+				THREADVALUE.result == null);
+
+	}
+
+	/**
+	 * Sets up the fixture, for example, open a network connection. This method
+	 * is called before a test is executed.
+	 */
+	protected void setUp() {
+	}
+
+	/**
+	 * Tears down the fixture, for example, close a network connection. This
+	 * method is called after a test is executed.
+	 */
+	protected void tearDown() {
+	}
+}