package org.apache.harmony.luni.tests.java.lang;
+import dalvik.annotation.AndroidOnly;
+import dalvik.annotation.BrokenTest;
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetNew;
+import dalvik.annotation.TestTargetClass;
+
+import java.security.Permission;
import java.util.Vector;
-// BEGIN android-changed
+@TestTargetClass(ThreadGroup.class)
public class ThreadGroupTest extends junit.framework.TestCase implements Thread.UncaughtExceptionHandler {
-// END android-changed
class MyThread extends Thread {
public volatile int heartBeat = 0;
try {
Thread.sleep(50);
} catch (InterruptedException e) {
+ break;
}
}
}
/**
* @tests java.lang.ThreadGroup#ThreadGroup(java.lang.String)
*/
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "ThreadGroup",
+ args = {java.lang.String.class}
+ )
public void test_ConstructorLjava_lang_String() {
// Test for method java.lang.ThreadGroup(java.lang.String)
// cleanup
newGroup.destroy();
-
+
+ newGroup = new ThreadGroup("");
+ assertEquals("", newGroup.getName());
+
+ newGroup = new ThreadGroup(null);
+ assertNull(newGroup.getName());
+
+ SecurityManager oldSm = System.getSecurityManager();
+ System.setSecurityManager(sm);
+ try {
+ new ThreadGroup(name);
+ fail("Should throw SecurityException");
+ } catch (SecurityException e) {
+ // expected
+ } finally {
+ System.setSecurityManager(oldSm);
+ }
}
-
+
/**
* @tests java.lang.ThreadGroup#ThreadGroup(java.lang.ThreadGroup,
* java.lang.String)
*/
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "ThreadGroup",
+ args = {java.lang.ThreadGroup.class, java.lang.String.class}
+ )
public void test_ConstructorLjava_lang_ThreadGroupLjava_lang_String() {
// Test for method java.lang.ThreadGroup(java.lang.ThreadGroup,
// java.lang.String)
} catch (IllegalThreadStateException e) {
newGroup = null;
}
- ;
+
assertNull("Can't create a subgroup of a destroyed group",
newGroup);
+
+ try {
+ new ThreadGroup(null, "name");
+ fail("NullPointerException is not thrown.");
+ } catch(NullPointerException npe) {
+ //expected
+ }
+
+ try {
+ new ThreadGroup(newGroup, null);
+ fail("NullPointerException is not thrown.");
+ } catch(NullPointerException npe) {
+ //expected
+ }
+
+ SecurityManager oldSm = System.getSecurityManager();
+ System.setSecurityManager(sm);
+ try {
+ new ThreadGroup(getRootThreadGroup(), "a name here");
+ fail("SecurityException was not thrown.");
+ } catch (SecurityException e) {
+ // expected
+ } finally {
+ System.setSecurityManager(oldSm);
+ }
}
/**
* @tests java.lang.ThreadGroup#activeCount()
*/
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "activeCount",
+ args = {}
+ )
public void test_activeCount() {
// Test for method int java.lang.ThreadGroup.activeCount()
ThreadGroup tg = new ThreadGroup("activeCount");
}
}
});
- int count = tg.activeCount();
- assertTrue("wrong active count: " + count, count == 0);
+ int beforeCount = tg.activeCount();
t1.start();
- count = tg.activeCount();
- assertTrue("wrong active count: " + count, count == 1);
+ int afterCount = tg.activeCount();
+ assertTrue("count of active threads should be increased",
+ (afterCount - beforeCount) == 1);
t1.interrupt();
try {
t1.join();
tg.destroy();
}
- // BEGIN android-added
/**
* @tests java.lang.ThreadGroup#activeGroupCount()
*/
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "activeGroupCount",
+ args = {}
+ )
public void test_activeGroupCount() {
+
ThreadGroup tg = new ThreadGroup("group count");
assertEquals("Incorrect number of groups",
0, tg.activeGroupCount());
Thread t1 = new Thread(tg, new Runnable() {
public void run() {
- // TODO Auto-generated method stub
+
}
});
assertEquals("Incorrect number of groups",
/**
* @tests java.lang.ThreadGroup#allowThreadSuspension(boolean)
*/
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "allowThreadSuspension",
+ args = {boolean.class}
+ )
@SuppressWarnings("deprecation")
public void test_allowThreadSuspensionZ() {
ThreadGroup tg = new ThreadGroup("thread suspension");
assertTrue("Thread suspention can not be changed",
tg.allowThreadSuspension(true));
}
- // END android-added
/**
* @tests java.lang.ThreadGroup#checkAccess()
*/
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "checkAccess",
+ args = {}
+ )
public void test_checkAccess() {
// Test for method void java.lang.ThreadGroup.checkAccess()
testRoot.destroy();
+ SecurityManager oldSm = System.getSecurityManager();
+ System.setSecurityManager(sm);
+ try {
+ testRoot.checkAccess();
+ fail("Should throw SecurityException");
+ } catch (SecurityException e) {
+ // expected
+ } finally {
+ System.setSecurityManager(oldSm);
+ }
+ }
+
+ /*
+ * Checks whether the current Thread is in the given list.
+ */
+ private boolean inListOfThreads(Thread[] threads) {
+ for (int i = 0; i < threads.length; i++) {
+ if (Thread.currentThread() == threads[i]) {
+ return true;
+ }
+ }
+
+ return false;
}
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "enumerate",
+ args = {java.lang.Thread[].class}
+ )
+ public void test_enumerateLThreadArray() {
+ int numThreads = initialThreadGroup.activeCount();
+ Thread[] listOfThreads = new Thread[numThreads];
+
+ int countThread = initialThreadGroup.enumerate(listOfThreads);
+ assertEquals(numThreads, countThread);
+ assertTrue("Current thread must be in enumeration of threads",
+ inListOfThreads(listOfThreads));
+
+ SecurityManager oldSm = System.getSecurityManager();
+ System.setSecurityManager(sm);
+ try {
+ initialThreadGroup.enumerate(listOfThreads);
+ fail("Should throw SecurityException");
+ } catch (SecurityException e) {
+ // expected
+ } finally {
+ System.setSecurityManager(oldSm);
+ }
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "enumerate",
+ args = {java.lang.Thread[].class, boolean.class}
+ )
+ public void test_enumerateLThreadArrayLZ() {
+ int numThreads = initialThreadGroup.activeCount();
+ Thread[] listOfThreads = new Thread[numThreads];
+
+ int countThread = initialThreadGroup.enumerate(listOfThreads, false);
+ assertEquals(numThreads, countThread);
+
+ countThread = initialThreadGroup.enumerate(listOfThreads, true);
+ assertEquals(numThreads, countThread);
+ assertTrue("Current thread must be in enumeration of threads",
+ inListOfThreads(listOfThreads));
+
+ ThreadGroup subGroup = new ThreadGroup(initialThreadGroup, "Test Group 1");
+ int subThreadsCount = 3;
+ Vector<MyThread> subThreads = populateGroupsWithThreads(subGroup,
+ subThreadsCount);
+
+ countThread = initialThreadGroup.enumerate(listOfThreads, true);
+ assertEquals(numThreads, countThread);
+ assertTrue("Current thread must be in enumeration of threads",
+ inListOfThreads(listOfThreads));
+
+ for(MyThread thr:subThreads) {
+ thr.start();
+ }
+ // lets give them some time to start
+ try {
+ Thread.sleep(500);
+ } catch (InterruptedException ie) {
+ fail("Should not be interrupted");
+ }
+ int numThreads2 = initialThreadGroup.activeCount();
+ listOfThreads = new Thread[numThreads2];
+
+ assertEquals(numThreads + subThreadsCount, numThreads2);
+
+ countThread = initialThreadGroup.enumerate(listOfThreads, true);
+ assertEquals(numThreads2, countThread);
+ assertTrue("Current thread must be in enumeration of threads",
+ inListOfThreads(listOfThreads));
+
+ for(MyThread thr:subThreads) {
+ thr.interrupt();
+ }
+ // lets give them some time to die
+ try {
+ Thread.sleep(500);
+ } catch (InterruptedException ie) {
+ fail("Should not be interrupted");
+ }
+
+ int numThreads3 = initialThreadGroup.activeCount();
+ listOfThreads = new Thread[numThreads3];
+
+ assertEquals(numThreads, numThreads3);
+
+ countThread = initialThreadGroup.enumerate(listOfThreads, false);
+ assertEquals(numThreads3, countThread);
+ assertTrue("Current thread must be in enumeration of threads",
+ inListOfThreads(listOfThreads));
+
+ SecurityManager oldSm = System.getSecurityManager();
+ System.setSecurityManager(sm);
+ try {
+ initialThreadGroup.enumerate(listOfThreads, true);
+ fail("Should throw SecurityException");
+ } catch (SecurityException e) {
+ // expected
+ } finally {
+ System.setSecurityManager(oldSm);
+ }
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "enumerate",
+ args = {java.lang.ThreadGroup[].class}
+ )
+ @BrokenTest("Fails in CTS environment, but passes in CoreTestRunner")
+ public void test_enumerateLThreadGroupArray() {
+ int numGroupThreads = initialThreadGroup.activeGroupCount();
+ ThreadGroup[] listOfGroups = new ThreadGroup[numGroupThreads];
+
+ int countGroupThread = initialThreadGroup.enumerate(listOfGroups);
+ assertEquals(numGroupThreads, countGroupThread);
+
+ ThreadGroup[] listOfGroups1 = new ThreadGroup[numGroupThreads + 1];
+ countGroupThread = initialThreadGroup.enumerate(listOfGroups1);
+ assertEquals(numGroupThreads, countGroupThread);
+ assertNull(listOfGroups1[listOfGroups1.length - 1]);
+
+ ThreadGroup[] listOfGroups2 = new ThreadGroup[numGroupThreads - 1];
+ countGroupThread = initialThreadGroup.enumerate(listOfGroups2);
+ assertEquals(numGroupThreads - 1, countGroupThread);
+
+ ThreadGroup thrGroup1 = new ThreadGroup("Test Group 1");
+ countGroupThread = thrGroup1.enumerate(listOfGroups);
+ assertEquals(0, countGroupThread);
+
+ SecurityManager oldSm = System.getSecurityManager();
+ System.setSecurityManager(sm);
+ try {
+ initialThreadGroup.enumerate(listOfGroups);
+ fail("Should throw SecurityException");
+ } catch (SecurityException e) {
+ // expected
+ } finally {
+ System.setSecurityManager(oldSm);
+ }
+ }
+
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "enumerate",
+ args = {java.lang.ThreadGroup[].class, boolean.class}
+ )
+ public void test_enumerateLThreadGroupArrayLZ() {
+ ThreadGroup thrGroup = new ThreadGroup("Test Group 1");
+ Vector<MyThread> subThreads = populateGroupsWithThreads(thrGroup, 3);
+ int numGroupThreads = thrGroup.activeGroupCount();
+ ThreadGroup[] listOfGroups = new ThreadGroup[numGroupThreads];
+
+ assertEquals(0, thrGroup.enumerate(listOfGroups, true));
+ assertEquals(0, thrGroup.enumerate(listOfGroups, false));
+
+ for(MyThread thr:subThreads) {
+ thr.start();
+ }
+
+ numGroupThreads = thrGroup.activeGroupCount();
+ listOfGroups = new ThreadGroup[numGroupThreads];
+
+ assertEquals(0, thrGroup.enumerate(listOfGroups, true));
+ assertEquals(0, thrGroup.enumerate(listOfGroups, false));
+
+ ThreadGroup subGroup1 = new ThreadGroup(thrGroup, "Test Group 2");
+ Vector<MyThread> subThreads1 = populateGroupsWithThreads(subGroup1, 3);
+ numGroupThreads = thrGroup.activeGroupCount();
+ listOfGroups = new ThreadGroup[numGroupThreads];
+
+ assertEquals(1, thrGroup.enumerate(listOfGroups, true));
+ assertEquals(1, thrGroup.enumerate(listOfGroups, false));
+
+ for(MyThread thr:subThreads1) {
+ thr.start();
+ }
+ numGroupThreads = thrGroup.activeGroupCount();
+ listOfGroups = new ThreadGroup[numGroupThreads];
+
+ assertEquals(1, thrGroup.enumerate(listOfGroups, true));
+ assertEquals(1, thrGroup.enumerate(listOfGroups, false));
+
+ for(MyThread thr:subThreads) {
+ thr.interrupt();
+ }
+
+ ThreadGroup subGroup2 = new ThreadGroup(subGroup1, "Test Group 3");
+ Vector<MyThread> subThreads2 = populateGroupsWithThreads(subGroup2, 3);
+ numGroupThreads = thrGroup.activeGroupCount();
+ listOfGroups = new ThreadGroup[numGroupThreads];
+
+ assertEquals(2, thrGroup.enumerate(listOfGroups, true));
+ assertEquals(1, thrGroup.enumerate(listOfGroups, false));
+
+ SecurityManager oldSm = System.getSecurityManager();
+ System.setSecurityManager(sm);
+ try {
+ thrGroup.enumerate(listOfGroups, true);
+ fail("Should throw SecurityException");
+ } catch (SecurityException e) {
+ // expected
+ } finally {
+ System.setSecurityManager(oldSm);
+ }
+ }
+
/**
* @tests java.lang.ThreadGroup#destroy()
*/
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "destroy",
+ args = {}
+ )
public void test_destroy() {
// Test for method void java.lang.ThreadGroup.destroy()
} catch (IllegalThreadStateException e) {
passed = true;
}
- ;
+
assertTrue("Destroyed child can't be destroyed again", passed);
}
} catch (IllegalThreadStateException e) {
passed = true;
}
- ;
+
assertTrue("Daemon should have been destroyed already", passed);
passed = false;
} catch (IllegalThreadStateException e) {
passed = true;
}
- ;
+
assertTrue("Daemon parent should have been destroyed automatically",
passed);
} catch (InterruptedException ie) {
fail("Should not be interrupted");
}
- ;
+
passed = false;
try {
} catch (IllegalThreadStateException e) {
passed = true;
}
- ;
+
assertTrue(
"Daemon group should have been destroyed already when last thread died",
passed);
} catch (InterruptedException ie) {
fail("Should not be interrupted");
}
- ;
+
passed = true;
try {
testRoot.destroy();
"Should be able to destroy a ThreadGroup that has no threads",
passed);
+ ThreadGroup tg = new ThreadGroup("ThreadGroup");
+ SecurityManager oldSm = System.getSecurityManager();
+ System.setSecurityManager(sm);
+ try {
+ originalCurrent.destroy();
+ fail("Should throw SecurityException");
+ } catch (SecurityException e) {
+ // expected
+ } finally {
+ System.setSecurityManager(oldSm);
+ }
}
/**
* @tests java.lang.ThreadGroup#destroy()
*/
+ @TestTargetNew(
+ level = TestLevel.PARTIAL,
+ notes = "Verifies IllegalThreadStateException.",
+ method = "destroy",
+ args = {}
+ )
public void test_destroy_subtest0() {
ThreadGroup group1 = new ThreadGroup("test_destroy_subtest0");
group1.destroy();
/**
* @tests java.lang.ThreadGroup#getMaxPriority()
*/
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "getMaxPriority",
+ args = {}
+ )
public void test_getMaxPriority() {
// Test for method int java.lang.ThreadGroup.getMaxPriority()
-
final ThreadGroup originalCurrent = getInitialThreadGroup();
ThreadGroup testRoot = new ThreadGroup(originalCurrent, "Test group");
/**
* @tests java.lang.ThreadGroup#getName()
*/
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "getName",
+ args = {}
+ )
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);
/**
* @tests java.lang.ThreadGroup#getParent()
*/
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "getParent",
+ args = {}
+ )
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");
testRoot.destroy();
}
- // BEGIN android-added
/**
* @tests java.lang.ThreadGroup#interrupt()
*/
private static boolean interrupted = false;
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "interrupt",
+ args = {}
+ )
public void test_interrupt() {
+
Thread.setDefaultUncaughtExceptionHandler(this);
ThreadGroup tg = new ThreadGroup("interrupt");
Thread t1 = new Thread(tg, new Runnable() {
}
assertTrue("Incorrect state of thread", interrupted);
tg.destroy();
+
+ ThreadGroup threadGroup = new ThreadGroup("securityCheck");
+ SecurityManager oldSm = System.getSecurityManager();
+ System.setSecurityManager(sm);
+ try {
+ threadGroup.interrupt();
+ fail("Should throw SecurityException");
+ } catch (SecurityException e) {
+ // expected
+ } finally {
+ System.setSecurityManager(oldSm);
+ }
}
- // END android-added
/**
* @tests java.lang.ThreadGroup#isDaemon()
*/
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "isDaemon",
+ args = {}
+ )
public void test_isDaemon() {
// Test for method boolean java.lang.ThreadGroup.isDaemon()
-
daemonTests();
-
}
- // BEGIN android-added
/**
* @tests java.lang.ThreadGroup#isDestroyed()
*/
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "isDestroyed",
+ args = {}
+ )
public void test_isDestroyed() {
final ThreadGroup originalCurrent = getInitialThreadGroup();
final ThreadGroup testRoot = new ThreadGroup(originalCurrent,
assertTrue("Test group already destroyed",
testRoot.isDestroyed());
}
- // END android-added
/**
* @tests java.lang.ThreadGroup#list()
*/
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "list",
+ args = {}
+ )
public void test_list() {
// Test for method void java.lang.ThreadGroup.list()
/**
* @tests java.lang.ThreadGroup#parentOf(java.lang.ThreadGroup)
*/
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "parentOf",
+ args = {java.lang.ThreadGroup.class}
+ )
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");
/**
* @tests java.lang.ThreadGroup#resume()
*/
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "resume",
+ args = {}
+ )
+ @AndroidOnly("RI does implement this method, whereas Android does not")
@SuppressWarnings("deprecation")
- 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);
+ public void test_resume() {
+ ThreadGroup group = new ThreadGroup("Foo");
+
+ Thread thread = launchFiveSecondDummyThread(group);
- final int THREADS_PER_GROUP = 2;
- final Vector<MyThread> threads = populateGroupsWithThreads(testRoot,
- THREADS_PER_GROUP);
-
- boolean[] isResumed = null;
try {
- try {
- for (int i = 0; i < threads.size(); i++) {
- Thread t = threads.elementAt(i);
- t.start();
- t.suspend();
- }
- // In 5.0, activeCount() only returns threads that are alive
- assertTrue("Internal error when populating ThreadGroups", testRoot
- .activeCount() == threads.size());
- } catch (OutOfMemoryError e) {
- for (int i = 0; i < threads.size(); i++) {
- Thread t = 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(500);
- } catch (InterruptedException ie) {
- fail("Should not have been interrupted");
- }
+ Thread.sleep(1000);
+ } catch (InterruptedException e) {
+ // Ignore
+ }
- isResumed = new boolean[threads.size()];
- boolean failed = false;
- for (int i = 0; i < isResumed.length; i++) {
- MyThread t = threads.elementAt(i);
- if (!failed) { // if one failed, don't waste time checking the
- // rest
- isResumed[i] = t.isActivelyRunning(1000);
- failed = failed | (!isResumed[i]);
- }
- t.stop(); // deprecated but effective
- }
+ // No-op in Android. Must neither have an effect nor throw an exception.
+ Thread.State state = thread.getState();
+ group.resume();
+ assertEquals(state, thread.getState());
- // Give them some time to really die
- try {
- Thread.sleep(500);
- } catch (InterruptedException ie) {
- fail("Should not have been interrupted");
- }
+ // Security checks are made even though method is not supported.
+ SecurityManager oldSm = System.getSecurityManager();
+ System.setSecurityManager(new ThreadSecurityManager());
+ try {
+ group.resume();
+ fail("Should throw SecurityException");
+ } catch (SecurityException e) {
+ // expected
} finally {
- // Make sure we do cleanup before returning
- testRoot.destroy();
+ System.setSecurityManager(oldSm);
}
-
- for (int i = 0; i < isResumed.length; i++) {
- assertTrue("Thread " + threads.elementAt(i)
- + " was not running when it was killed", isResumed[i]);
+
+ try {
+ thread.join();
+ } catch (InterruptedException e) {
+ // Ignore
}
-
- assertEquals("Method destroy must have problems",
- 0, testRoot.activeCount());
-
}
/**
* @tests java.lang.ThreadGroup#setDaemon(boolean)
*/
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "setDaemon",
+ args = {boolean.class}
+ )
public void test_setDaemonZ() {
// Test for method void java.lang.ThreadGroup.setDaemon(boolean)
-
daemonTests();
+
+ final ThreadGroup testRoot = new ThreadGroup("Test group");
+ testRoot.setDaemon(true);
+
+ SecurityManager oldSm = System.getSecurityManager();
+ System.setSecurityManager(sm);
+
+ try {
+ new ThreadGroup("");
+ fail("Should throw SecurityException");
+ } catch (SecurityException e) {
+ // expected
+ } finally {
+ System.setSecurityManager(oldSm);
+ }
}
/**
* @tests java.lang.ThreadGroup#setMaxPriority(int)
*/
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "setMaxPriority",
+ args = {int.class}
+ )
public void test_setMaxPriorityI() {
// Test for method void java.lang.ThreadGroup.setMaxPriority(int)
-
final ThreadGroup originalCurrent = getInitialThreadGroup();
ThreadGroup testRoot = new ThreadGroup(originalCurrent, "Test group");
} finally {
System.setSecurityManager(null);
}
+
+ SecurityManager oldSm = System.getSecurityManager();
+ System.setSecurityManager(sm);
+
+ try {
+ testRoot.setMaxPriority(Thread.MAX_PRIORITY);
+ fail("Should throw SecurityException");
+ } catch (SecurityException e) {
+ // expected
+ } finally {
+ System.setSecurityManager(oldSm);
+ }
}
/**
* @tests java.lang.ThreadGroup#stop()
*/
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "stop",
+ args = {}
+ )
+ @AndroidOnly("RI does implement this method, whereas Android does not")
@SuppressWarnings("deprecation")
- 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<MyThread> threads = populateGroupsWithThreads(testRoot,
- THREADS_PER_GROUP);
+ public void test_stop() {
+ ThreadGroup group = new ThreadGroup("Foo");
+
+ Thread thread = launchFiveSecondDummyThread(group);
try {
- for (int i = 0; i < threads.size(); i++) {
- Thread t = threads.elementAt(i);
- t.start();
- }
- } catch (OutOfMemoryError e) {
- for (int i = 0; i < threads.size(); i++) {
- Thread t = threads.elementAt(i);
- t.stop(); // deprecated but effective
- }
- throw e;
+ Thread.sleep(1000);
+ } catch (InterruptedException e) {
+ // Ignore
}
- // Now that they are all running, let's stop the ThreadGroup
- testRoot.stop();
+ // No-op in Android. Must neither have an effect nor throw an exception.
+ Thread.State state = thread.getState();
+ group.stop();
+ assertEquals(state, thread.getState());
- // 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 = 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;
- }
+ // Security checks are made even though method is not supported.
+ SecurityManager oldSm = System.getSecurityManager();
+ System.setSecurityManager(new ThreadSecurityManager());
+ try {
+ group.stop();
+ fail("Should throw SecurityException");
+ } catch (SecurityException e) {
+ // expected
+ } finally {
+ System.setSecurityManager(oldSm);
}
+
+ try {
+ thread.join();
+ } catch (InterruptedException e) {
+ // Ignore
+ }
+ }
- // To make sure that even if we fail, we exit in a clean state
- testRoot.destroy();
-
- assertTrue("Thread should be dead by now", passed);
-
- assertEquals("Method destroy (or wipeAllThreads) must have problems",
- 0, testRoot.activeCount());
-
+ private Thread launchFiveSecondDummyThread(ThreadGroup group) {
+ Thread thread = new Thread(group, "Bar") {
+ public void run() {
+ try {
+ Thread.sleep(5000);
+ } catch (InterruptedException e) {
+ // Ignore
+ }
+ }
+ };
+
+ thread.start();
+
+ return thread;
}
+ private class ThreadSecurityManager extends SecurityManager {
+ public void checkPermission(Permission perm) {
+ }
+
+ public void checkAccess(Thread t) {
+ throw new SecurityException();
+ }
+ };
+
/**
* @tests java.lang.ThreadGroup#suspend()
*/
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "suspend",
+ args = {}
+ )
+ @AndroidOnly("RI does implement this method, whereas Android does not")
@SuppressWarnings("deprecation")
- public void test_suspend() throws OutOfMemoryError {
- // Test for method void java.lang.ThreadGroup.suspend()
-
- final ThreadGroup originalCurrent = getInitialThreadGroup();
+ public void test_suspend() {
+ ThreadGroup group = new ThreadGroup("Foo");
+
+ Thread thread = launchFiveSecondDummyThread(group);
- final ThreadGroup testRoot = new ThreadGroup(originalCurrent,
- "Test group");
- final int DEPTH = 2;
- buildRandomTreeUnder(testRoot, DEPTH);
-
- final int THREADS_PER_GROUP = 2;
- final Vector<MyThread> threads = populateGroupsWithThreads(testRoot,
- THREADS_PER_GROUP);
-
- boolean passed = false;
try {
- try {
- for (int i = 0; i < threads.size(); i++) {
- Thread t = threads.elementAt(i);
- t.start();
- }
- } catch (OutOfMemoryError e) {
- for (int i = 0; i < threads.size(); i++) {
- Thread t = threads.elementAt(i);
- t.stop(); // deprecated but effective
- }
- throw e;
- }
+ Thread.sleep(1000);
+ } catch (InterruptedException e) {
+ // Ignore
+ }
- // Now that they are all running, let's suspend the ThreadGroup
- testRoot.suspend();
+ // No-op in Android. Must neither have an effect nor throw an exception.
+ Thread.State state = thread.getState();
+ group.suspend();
+ assertEquals(state, thread.getState());
- passed = allSuspended(threads);
- assertTrue("Should be able to wipe all threads (allSuspended="
- + passed + ")", wipeAllThreads(testRoot));
+ // Security checks are made even though method is not supported.
+ SecurityManager oldSm = System.getSecurityManager();
+ System.setSecurityManager(new ThreadSecurityManager());
+ try {
+ group.suspend();
+ fail("Should throw SecurityException");
+ } catch (SecurityException e) {
+ // expected
} finally {
-
- // We can't destroy a ThreadGroup if we do not make sure it has no
- // threads at all
- testRoot.stop();
- long waitTime = 5000;
- for (int i = 0; i < threads.size(); i++) {
- Thread t = threads.elementAt(i);
- while (t.isAlive() && waitTime >= 0) {
- try {
- Thread.sleep(10);
- waitTime -= 10;
- } catch (InterruptedException e) {
- fail("unexpected interruption");
- }
- }
- if (waitTime < 0) {
- fail("stop() has not stopped threads in ThreadGroup 'testRoot'");
- }
- }
- // Make sure we cleanup before returning from the method
- testRoot.destroy();
+ System.setSecurityManager(oldSm);
+ }
+
+ try {
+ thread.join();
+ } catch (InterruptedException e) {
+ // Ignore
}
- assertTrue("All threads should be suspended", passed);
-
- assertEquals("Method destroy (or wipeAllThreads) must have problems",
- 0, testRoot.activeCount());
-
}
/**
* @tests java.lang.ThreadGroup#toString()
*/
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "toString",
+ args = {}
+ )
public void test_toString() {
// Test for method java.lang.String java.lang.ThreadGroup.toString()
-
final ThreadGroup originalCurrent = getInitialThreadGroup();
final String tGroupName = "Test group";
* @tests java.lang.ThreadGroup#uncaughtException(java.lang.Thread,
* java.lang.Throwable)
*/
+ @TestTargetNew(
+ level = TestLevel.COMPLETE,
+ notes = "",
+ method = "uncaughtException",
+ args = {java.lang.Thread.class, java.lang.Throwable.class}
+ )
@SuppressWarnings("deprecation")
public void test_uncaughtExceptionLjava_lang_ThreadLjava_lang_Throwable() {
// Test for method void
// java.lang.Throwable)
final ThreadGroup originalCurrent = getInitialThreadGroup();
-
+
// indices for the array defined below
final int TEST_DEATH = 0;
final int TEST_OTHER = 1;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// - - - - - - -
testRoot = new ThreadGroup(originalCurrent,
- "Test killing a Thread, forcing it to throw ThreadDeath") {
- @Override
- 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)") {
- @Override
- 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") {
@Override
public void uncaughtException(Thread t, Throwable e) {
assertTrue(
"Any thread should notify its ThreadGroup about its own death, even if suicide:"
+ testRoot, passed[TEST_FORCING_THROW_THREAD_DEATH]);
-
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// - - - - - - -
testRoot.destroy();
assertTrue("A thread should not call uncaughtException when it dies:"
+ testRoot, passed[TEST_DEATH]);
-
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// - - - - - - -
assertTrue(
"Any thread should notify its ThreadGroup about an uncaught exception:"
+ testRoot, passed[TEST_OTHER]);
-
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// - - - - - - -
assertTrue(
"Any uncaughtException in uncaughtException should be no-op:"
+ testRoot, passed[TEST_EXCEPTION_IN_UNCAUGHT]);
-
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// - - - - - - -
testRoot.destroy();
}
- // BEGIN android-added
/*
* @see java.lang.Thread.UncaughtExceptionHandler#uncaughtException(java.lang.Thread, java.lang.Throwable)
*/
interrupted = true;
Thread.setDefaultUncaughtExceptionHandler(null);
}
- // END android-added
@Override
protected void setUp() {
assertTrue("Setting daemon&getting does not work", !testRoot.isDaemon());
testRoot.destroy();
-
}
private boolean wipeAllThreads(final ThreadGroup aGroup) {
for (ThreadGroup element : children) {
ok = ok && wipeAllThreads(element);
}
-
return ok;
-
}
private boolean wipeSideEffectThreads(ThreadGroup aGroup) {
for (ThreadGroup element : children) {
ok = ok && wipeSideEffectThreads(element);
- if (element.getName().equals("Test Group")
+ if(element.getName() != null) {
+ if (element.getName().equals("Test Group")
|| element.getName().equals("foo")
|| element.getName().equals("jp")) {
- element.destroy();
+ element.destroy();
+ }
}
}
try {
return rootThreadGroup;
}
+
+ SecurityManager sm = new SecurityManager() {
+
+ public void checkPermission(Permission perm) {
+ }
+
+ public void checkAccess(ThreadGroup g) {
+ throw new SecurityException();
+ }
+ };
}