1cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath/* 2cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath * Licensed to the Apache Software Foundation (ASF) under one or more 3cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath * contributor license agreements. See the NOTICE file distributed with 4cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath * this work for additional information regarding copyright ownership. 5cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath * The ASF licenses this file to You under the Apache License, Version 2.0 6cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath * (the "License"); you may not use this file except in compliance with 7cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath * the License. You may obtain a copy of the License at 8cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath * 9cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath * http://www.apache.org/licenses/LICENSE-2.0 10cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath * 11cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath * Unless required by applicable law or agreed to in writing, software 12cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath * distributed under the License is distributed on an "AS IS" BASIS, 13cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath * See the License for the specific language governing permissions and 15cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath * limitations under the License. 16cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath */ 17cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath 18ab762bb740405d0fefcccf4a0899a234f995be13Narayan Kamathpackage org.apache.harmony.tests.java.lang; 19cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath 20cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamathimport java.util.Vector; 21cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath 22cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamathpublic class ThreadGroupTest extends junit.framework.TestCase { 23cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath 24071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller private TestThreadDefaultUncaughtExceptionHandler testThreadDefaultUncaughtExceptionHandler; 25071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller private ThreadGroup rootThreadGroup; 26071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller private ThreadGroup initialThreadGroup; 27071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller private Thread.UncaughtExceptionHandler originalThreadDefaultUncaughtExceptionHandler; 28cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath 29071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller @Override 30071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller protected void setUp() { 31071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller initialThreadGroup = Thread.currentThread().getThreadGroup(); 32071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller rootThreadGroup = initialThreadGroup; 33071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller while (rootThreadGroup.getParent() != null) { 34071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller rootThreadGroup = rootThreadGroup.getParent(); 35cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath } 36cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath 37071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller // When running as a CTS test Android will by default treat an uncaught exception as a 38071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller // fatal application error and kill the test. To avoid this the default 39071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller // UncaughtExceptionHandler is replaced for the duration of the test (if one exists). It 40071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller // also allows us to test that ultimately the default handler is called if a ThreadGroup's 41071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller // UncaughtExceptionHandler doesn't handle an exception. 42071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller originalThreadDefaultUncaughtExceptionHandler = Thread.getDefaultUncaughtExceptionHandler(); 43071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller testThreadDefaultUncaughtExceptionHandler = new TestThreadDefaultUncaughtExceptionHandler(); 44071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller Thread.setDefaultUncaughtExceptionHandler(testThreadDefaultUncaughtExceptionHandler); 45cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath } 46cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath 47071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller @Override 48071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller protected void tearDown() { 49071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller // Reset the uncaughtExceptionHandler to what it was when the test began. 50071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller Thread.setDefaultUncaughtExceptionHandler(originalThreadDefaultUncaughtExceptionHandler); 51071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller } 52cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath 53071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller // Test for method java.lang.ThreadGroup(java.lang.String) 54cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath public void test_ConstructorLjava_lang_String() { 55071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller // Unfortunately we have to use other APIs as well as we test the constructor 56071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller ThreadGroup initial = initialThreadGroup; 57cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath final String name = "Test name"; 58071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller ThreadGroup newGroup = new ThreadGroup(name); 59cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath assertTrue( 60cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath "Has to be possible to create a subgroup of current group using simple constructor", 61cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath newGroup.getParent() == initial); 62cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath assertTrue("Name has to be correct", newGroup.getName().equals(name)); 63cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath 64cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath // cleanup 65cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath newGroup.destroy(); 66cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath } 67cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath 68071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller // Test for method java.lang.ThreadGroup(java.lang.ThreadGroup, java.lang.String) 69cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath public void test_ConstructorLjava_lang_ThreadGroupLjava_lang_String() { 70071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller // Unfortunately we have to use other APIs as well as we test the constructor 71cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath ThreadGroup newGroup = null; 72cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath try { 73cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath newGroup = new ThreadGroup(null, null); 74cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath } catch (NullPointerException e) { 75cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath } 76071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller assertNull("Can't create a ThreadGroup with a null parent", newGroup); 77cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath 78071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller newGroup = new ThreadGroup(initialThreadGroup, null); 79cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath assertTrue("Has to be possible to create a subgroup of current group", 80cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath newGroup.getParent() == Thread.currentThread().getThreadGroup()); 81cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath 82cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath // Lets start all over 83cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath newGroup.destroy(); 84cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath 85071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller newGroup = new ThreadGroup(rootThreadGroup, "a name here"); 86cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath assertTrue("Has to be possible to create a subgroup of root group", 87071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller newGroup.getParent() == rootThreadGroup); 88cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath 89cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath // Lets start all over 90cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath newGroup.destroy(); 91cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath 92cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath try { 93cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath newGroup = new ThreadGroup(newGroup, "a name here"); 94cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath } catch (IllegalThreadStateException e) { 95cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath newGroup = null; 96cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath } 97071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller assertNull("Can't create a subgroup of a destroyed group", newGroup); 98cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath } 99cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath 100071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller // Test for method int java.lang.ThreadGroup.activeCount() 101cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath public void test_activeCount() { 102cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath ThreadGroup tg = new ThreadGroup("activeCount"); 103cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath Thread t1 = new Thread(tg, new Runnable() { 104cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath public void run() { 105cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath try { 106cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath Thread.sleep(5000); 107cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath } catch (InterruptedException e) { 108cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath } 109cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath } 110cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath }); 111cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath int count = tg.activeCount(); 112cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath assertTrue("wrong active count: " + count, count == 0); 113cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath t1.start(); 114cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath count = tg.activeCount(); 115cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath assertTrue("wrong active count: " + count, count == 1); 116cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath t1.interrupt(); 117cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath try { 118cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath t1.join(); 119cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath } catch (InterruptedException e) { 120cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath } 121cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath // cleanup 122cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath tg.destroy(); 123cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath } 124cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath 125071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller // Test for method void java.lang.ThreadGroup.destroy() 126cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath public void test_destroy() { 127071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller final ThreadGroup originalCurrent = initialThreadGroup; 128cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath ThreadGroup testRoot = new ThreadGroup(originalCurrent, "Test group"); 129cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath final int DEPTH = 4; 130cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath final Vector<ThreadGroup> subgroups = buildRandomTreeUnder(testRoot, DEPTH); 131cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath 132cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath // destroy them all 133cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath testRoot.destroy(); 134cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath 135cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath for (int i = 0; i < subgroups.size(); i++) { 136cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath ThreadGroup child = subgroups.elementAt(i); 137071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller assertEquals("Destroyed child can't have children", 0, child.activeCount()); 138cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath boolean passed = false; 139cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath try { 140cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath child.destroy(); 141cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath } catch (IllegalThreadStateException e) { 142cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath passed = true; 143cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath } 144cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath assertTrue("Destroyed child can't be destroyed again", passed); 145cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath } 146cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath 147cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath testRoot = new ThreadGroup(originalCurrent, "Test group (daemon)"); 148cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath testRoot.setDaemon(true); 149cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath 150cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath ThreadGroup child = new ThreadGroup(testRoot, "daemon child"); 151cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath 152cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath // If we destroy the last daemon's child, the daemon should get destroyed 153cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath // as well 154cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath child.destroy(); 155cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath 156cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath boolean passed = false; 157cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath try { 158cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath child.destroy(); 159cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath } catch (IllegalThreadStateException e) { 160cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath passed = true; 161cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath } 162cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath assertTrue("Daemon should have been destroyed already", passed); 163cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath 164cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath passed = false; 165cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath try { 166cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath testRoot.destroy(); 167cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath } catch (IllegalThreadStateException e) { 168cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath passed = true; 169cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath } 170cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath assertTrue("Daemon parent should have been destroyed automatically", 171cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath passed); 172cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath 173cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath assertTrue( 174cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath "Destroyed daemon's child should not be in daemon's list anymore", 175cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath !arrayIncludes(groups(testRoot), child)); 176cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath assertTrue("Destroyed daemon should not be in parent's list anymore", 177cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath !arrayIncludes(groups(originalCurrent), testRoot)); 178cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath 179cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath testRoot = new ThreadGroup(originalCurrent, "Test group (daemon)"); 180cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath testRoot.setDaemon(true); 181cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath Thread noOp = new Thread(testRoot, null, "no-op thread") { 182cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath @Override 183cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath public void run() { 184cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath } 185cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath }; 186cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath noOp.start(); 187cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath 188cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath // Wait for the no-op thread to run inside daemon ThreadGroup 189071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller waitForThreadToDieUninterrupted(noOp); 190cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath 191cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath passed = false; 192cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath try { 193cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath child.destroy(); 194cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath } catch (IllegalThreadStateException e) { 195cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath passed = true; 196cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath } 197071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller assertTrue("Daemon group should have been destroyed already when last thread died", passed); 198cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath 199cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath testRoot = new ThreadGroup(originalCurrent, "Test group (daemon)"); 200cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath noOp = new Thread(testRoot, null, "no-op thread") { 201cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath @Override 202cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath public void run() { 203cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath try { 204cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath Thread.sleep(500); 205cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath } catch (InterruptedException ie) { 206cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath fail("Should not be interrupted"); 207cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath } 208cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath } 209cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath }; 210cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath 211071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller // Has to execute the next lines in an interval < the sleep interval of the no-op thread 212cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath noOp.start(); 213cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath passed = false; 214cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath try { 215cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath testRoot.destroy(); 216cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath } catch (IllegalThreadStateException its) { 217cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath passed = true; 218cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath } 219cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath assertTrue("Can't destroy a ThreadGroup that has threads", passed); 220cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath 221071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller // But after the thread dies, we have to be able to destroy the thread group 222071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller waitForThreadToDieUninterrupted(noOp); 223cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath passed = true; 224cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath try { 225cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath testRoot.destroy(); 226cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath } catch (IllegalThreadStateException its) { 227cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath passed = false; 228cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath } 229071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller assertTrue("Should be able to destroy a ThreadGroup that has no threads", passed); 230cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath } 231cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath 232071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller // Test for method java.lang.ThreadGroup.destroy() 233cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath public void test_destroy_subtest0() { 234cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath ThreadGroup group1 = new ThreadGroup("test_destroy_subtest0"); 235cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath group1.destroy(); 236cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath try { 237cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath new Thread(group1, "test_destroy_subtest0"); 238cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath fail("should throw IllegalThreadStateException"); 239cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath } catch (IllegalThreadStateException e) { 240cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath } 241cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath } 242cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath 243071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller // Test for method int java.lang.ThreadGroup.getMaxPriority() 244cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath public void test_getMaxPriority() { 245071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller final ThreadGroup originalCurrent = initialThreadGroup; 246cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath ThreadGroup testRoot = new ThreadGroup(originalCurrent, "Test group"); 247cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath 248cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath boolean passed = true; 249cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath try { 250cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath testRoot.setMaxPriority(Thread.MIN_PRIORITY); 251cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath } catch (IllegalArgumentException iae) { 252cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath passed = false; 253cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath } 254cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath assertTrue("Should be able to set priority", passed); 255cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath 256071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller assertTrue("New value should be the same as we set", 257071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller testRoot.getMaxPriority() == Thread.MIN_PRIORITY); 258cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath 259cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath testRoot.destroy(); 260cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath } 261cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath 262071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller // Test for method java.lang.String java.lang.ThreadGroup.getName() 263cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath public void test_getName() { 264071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller final ThreadGroup originalCurrent = initialThreadGroup; 265cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath final String name = "Test group"; 266cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath final ThreadGroup testRoot = new ThreadGroup(originalCurrent, name); 267cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath 268071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller assertTrue("Setting a name&getting does not work", testRoot.getName().equals(name)); 269cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath 270cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath testRoot.destroy(); 271cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath } 272cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath 273071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller // Test for method java.lang.ThreadGroup java.lang.ThreadGroup.getParent() 274cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath public void test_getParent() { 275071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller final ThreadGroup originalCurrent = initialThreadGroup; 276cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath ThreadGroup testRoot = new ThreadGroup(originalCurrent, "Test group"); 277cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath 278cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath assertTrue("Parent is wrong", testRoot.getParent() == originalCurrent); 279cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath 280cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath // Create some groups, nested some levels. 281cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath final int TOTAL_DEPTH = 5; 282cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath ThreadGroup current = testRoot; 283cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath Vector<ThreadGroup> groups = new Vector<ThreadGroup>(); 284cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath // To maintain the invariant that a thread in the Vector is parent 285cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath // of the next one in the collection (and child of the previous one) 286cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath groups.addElement(testRoot); 287cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath 288cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath for (int i = 0; i < TOTAL_DEPTH; i++) { 289cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath current = new ThreadGroup(current, "level " + i); 290cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath groups.addElement(current); 291cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath } 292cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath 293cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath // Now we walk the levels down, checking if parent is ok 294cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath for (int i = 1; i < groups.size(); i++) { 295cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath current = groups.elementAt(i); 296cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath ThreadGroup previous = groups.elementAt(i - 1); 297cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath assertTrue("Parent is wrong", current.getParent() == previous); 298cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath } 299cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath 300cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath testRoot.destroy(); 301cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath } 302cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath 303071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller // Test for method void java.lang.ThreadGroup.list() 304cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath public void test_list() { 305071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller final ThreadGroup originalCurrent = initialThreadGroup; 306071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller final ThreadGroup testRoot = new ThreadGroup(originalCurrent, "Test group"); 307cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath 308cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath // First save the original System.out 309cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath java.io.PrintStream originalOut = System.out; 310cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath 311cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath try { 312071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller java.io.ByteArrayOutputStream contentsStream = new java.io.ByteArrayOutputStream(100); 313cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath java.io.PrintStream newOut = new java.io.PrintStream(contentsStream); 314cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath 315cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath // We have to "redirect" System.out to test the method 'list' 316cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath System.setOut(newOut); 317cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath 318cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath originalCurrent.list(); 319cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath 320cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath /* 321071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller * The output has to look like this: 322071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller * 323071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller * java.lang.ThreadGroup[name=main,maxpri=10] Thread[main,5,main] 324071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller * java.lang.ThreadGroup[name=Test group,maxpri=10] 325071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller */ 326cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath String contents = new String(contentsStream.toByteArray()); 327cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath boolean passed = (contents.indexOf("ThreadGroup[name=main") != -1) && 328cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath (contents.indexOf("Thread[") != -1) && 329cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath (contents.indexOf("ThreadGroup[name=Test group") != -1); 330cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath assertTrue("'list()' does not print expected contents. " 331cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath + "Result from list: " 332cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath + contents, passed); 333cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath // Do proper cleanup 334cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath testRoot.destroy(); 335cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath 336cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath } finally { 337cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath // No matter what, we need to restore the original System.out 338cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath System.setOut(originalOut); 339cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath } 340cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath } 341cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath 342071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller // Test for method boolean java.lang.ThreadGroup.parentOf(java.lang.ThreadGroup) 343cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath public void test_parentOfLjava_lang_ThreadGroup() { 344071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller final ThreadGroup originalCurrent = initialThreadGroup; 345cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath final ThreadGroup testRoot = new ThreadGroup(originalCurrent, 346cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath "Test group"); 347cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath final int DEPTH = 4; 348cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath buildRandomTreeUnder(testRoot, DEPTH); 349cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath 350cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath final ThreadGroup[] allChildren = allGroups(testRoot); 351cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath for (ThreadGroup element : allChildren) { 352071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller assertTrue("Have to be parentOf all children", testRoot.parentOf(element)); 353cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath } 354cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath 355cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath assertTrue("Have to be parentOf itself", testRoot.parentOf(testRoot)); 356cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath 357cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath testRoot.destroy(); 358cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath assertTrue("Parent can't have test group as subgroup anymore", 359cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath !arrayIncludes(groups(testRoot.getParent()), testRoot)); 360cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath } 361cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath 362071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller // Test for method boolean java.lang.ThreadGroup.isDaemon() and 363071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller // void java.lang.ThreadGroup.setDaemon(boolean) 364071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller public void test_setDaemon_isDaemon() { 365071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller final ThreadGroup originalCurrent = initialThreadGroup; 366071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller final ThreadGroup testRoot = new ThreadGroup(originalCurrent, 367071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller "Test group"); 368cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath 369071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller testRoot.setDaemon(true); 370071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller assertTrue("Setting daemon&getting does not work", testRoot.isDaemon()); 371cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath 372071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller testRoot.setDaemon(false); 373071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller assertTrue("Setting daemon&getting does not work", !testRoot.isDaemon()); 374071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller 375071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller testRoot.destroy(); 376cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath } 377cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath 378cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath /* 379cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath * java.lang.ThreadGroupt#setDaemon(boolean) 380cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath */ 381cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath public void test_setDaemon_Parent_Child() { 382cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath ThreadGroup ptg = new ThreadGroup("Parent"); 383cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath ThreadGroup ctg = new ThreadGroup(ptg, "Child"); 384cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath 385cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath ctg.setDaemon(true); 386cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath assertTrue(ctg.isDaemon()); 387cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath 388cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath ctg.setDaemon(false); 389cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath assertFalse(ctg.isDaemon()); 390cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath 391cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath ptg.setDaemon(true); 392cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath assertFalse(ctg.isDaemon()); 393cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath 394cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath ptg.setDaemon(false); 395cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath assertFalse(ctg.isDaemon()); 396cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath } 397cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath 398071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller // Test for method void java.lang.ThreadGroup.setMaxPriority(int) 399cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath public void test_setMaxPriorityI() { 400071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller final ThreadGroup originalCurrent = initialThreadGroup; 401cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath ThreadGroup testRoot = new ThreadGroup(originalCurrent, "Test group"); 402cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath 403cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath boolean passed; 404cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath 405cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 406cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath 407cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath int currentMax = testRoot.getMaxPriority(); 408cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath testRoot.setMaxPriority(Thread.MAX_PRIORITY + 1); 409cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath passed = testRoot.getMaxPriority() == currentMax; 410cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath assertTrue( 411cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath "setMaxPriority: Any value higher than the current one is ignored. Before: " 412cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath + currentMax + " , after: " + testRoot.getMaxPriority(), 413cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath passed); 414cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath 415cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 416cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath 417cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath currentMax = testRoot.getMaxPriority(); 418cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath testRoot.setMaxPriority(Thread.MIN_PRIORITY - 1); 419cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath passed = testRoot.getMaxPriority() == Thread.MIN_PRIORITY; 420cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath assertTrue( 421cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath "setMaxPriority: Any value smaller than MIN_PRIORITY is adjusted to MIN_PRIORITY. Before: " 422071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller + currentMax + " , after: " + testRoot.getMaxPriority(), passed); 423cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath 424cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 425cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath 426cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath testRoot.destroy(); 427cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath testRoot = new ThreadGroup(originalCurrent, "Test group"); 428cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath 429cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath // Create some groups, nested some levels. Each level will have maxPrio 430cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath // 1 unit smaller than the parent's. However, there can't be a group 431cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath // with priority < Thread.MIN_PRIORITY 432cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath final int TOTAL_DEPTH = testRoot.getMaxPriority() - Thread.MIN_PRIORITY 433cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath - 2; 434cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath ThreadGroup current = testRoot; 435cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath for (int i = 0; i < TOTAL_DEPTH; i++) { 436cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath current = new ThreadGroup(current, "level " + i); 437cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath } 438cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath 439cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath // Now we walk the levels down, changing the maxPrio and later verifying 440cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath // that the value is indeed 1 unit smaller than the parent's maxPrio. 441cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath int maxPrio, parentMaxPrio; 442cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath current = testRoot; 443cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath 444cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath // To maintain the invariant that when we are to modify a child, 445cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath // its maxPriority is always 1 unit smaller than its parent's. 446cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath // We have to set it for the root manually, and the loop does the rest 447cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath // for all the other sub-levels 448cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath current.setMaxPriority(current.getParent().getMaxPriority() - 1); 449cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath 450cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath for (int i = 0; i < TOTAL_DEPTH; i++) { 451cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath maxPrio = current.getMaxPriority(); 452cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath parentMaxPrio = current.getParent().getMaxPriority(); 453cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath 454cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath ThreadGroup[] children = groups(current); 455cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath assertEquals("Can only have 1 subgroup", 1, children.length); 456cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath current = children[0]; 457cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath assertTrue( 458cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath "Had to be 1 unit smaller than parent's priority in iteration=" 459cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath + i + " checking->" + current, 460cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath maxPrio == parentMaxPrio - 1); 461cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath current.setMaxPriority(maxPrio - 1); 462cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath 463cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath // The next test is sort of redundant, since in next iteration it 464cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath // will be the parent tGroup, so the test will be done. 465cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath assertTrue("Had to be possible to change max priority", current 466cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath .getMaxPriority() == maxPrio - 1); 467cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath } 468cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath 469cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath assertTrue( 470cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath "Priority of leaf child group has to be much smaller than original root group", 471071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller current.getMaxPriority() == testRoot.getMaxPriority() - TOTAL_DEPTH); 472cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath 473cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath testRoot.destroy(); 474cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath 475cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 476cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath 477cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath passed = true; 478cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath testRoot = new ThreadGroup(originalCurrent, "Test group"); 479cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath try { 480cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath testRoot.setMaxPriority(Thread.MAX_PRIORITY); 481cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath } catch (IllegalArgumentException iae) { 482cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath passed = false; 483cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath } 484cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath assertTrue( 485cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath "Max Priority = Thread.MAX_PRIORITY should be possible if the test is run with default system ThreadGroup as root", 486cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath passed); 487cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath testRoot.destroy(); 488cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath } 489cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath 490071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller /* 491071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller * Test for method void java.lang.ThreadGroup.uncaughtException(java.lang.Thread, 492071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller * java.lang.Throwable) 493071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller * Tests if a Thread tells its ThreadGroup about ThreadDeath. 494cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath */ 495071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller public void test_uncaughtException_threadDeath() { 496071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller final boolean[] passed = new boolean[1]; 497cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath 498071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller ThreadGroup testRoot = new ThreadGroup(rootThreadGroup, 499cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath "Test Forcing a throw of ThreadDeath") { 500cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath @Override 501cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath public void uncaughtException(Thread t, Throwable e) { 502cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath if (e instanceof ThreadDeath) { 503071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller passed[0] = true; 504cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath } 505cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath // always forward, any exception 506cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath super.uncaughtException(t, e); 507cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath } 508cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath }; 509cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath 510071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller final ThreadDeath threadDeath = new ThreadDeath(); 511071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller Thread thread = new Thread(testRoot, null, "suicidal thread") { 512cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath @Override 513cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath public void run() { 514071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller throw threadDeath; 515cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath } 516cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath }; 517cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath thread.start(); 518071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller waitForThreadToDieUninterrupted(thread); 519071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller testThreadDefaultUncaughtExceptionHandler.assertWasCalled(thread, threadDeath); 520071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller 521cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath testRoot.destroy(); 522cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath assertTrue( 523cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath "Any thread should notify its ThreadGroup about its own death, even if suicide:" 524071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller + testRoot, passed[0]); 525071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller } 526cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath 527071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller /* 528071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller * Test for method void java.lang.ThreadGroup.uncaughtException(java.lang.Thread, 529071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller * java.lang.Throwable) 530071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller * Test if a Thread tells its ThreadGroup about a natural (non-exception) death. 531071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller */ 532071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller public void test_uncaughtException_naturalDeath() { 533071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller final boolean[] failed = new boolean[1]; 534cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath 535071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller ThreadGroup testRoot = new ThreadGroup(initialThreadGroup, "Test ThreadDeath") { 536cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath @Override 537cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath public void uncaughtException(Thread t, Throwable e) { 538071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller failed[0] = true; 539071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller 540071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller // always forward any exception 541cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath super.uncaughtException(t, e); 542cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath } 543cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath }; 544cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath 545071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller Thread thread = new Thread(testRoot, null, "no-op thread"); 546cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath thread.start(); 547071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller waitForThreadToDieUninterrupted(thread); 548071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller testThreadDefaultUncaughtExceptionHandler.assertWasNotCalled(); 549cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath testRoot.destroy(); 550071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller assertFalse("A thread should not call uncaughtException when it dies:" 551071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller + testRoot, failed[0]); 552071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller } 553cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath 554071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller /* 555071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller * Test for method void java.lang.ThreadGroup.uncaughtException(java.lang.Thread, 556071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller * java.lang.Throwable) 557071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller * Test if a Thread tells its ThreadGroup about an Exception 558071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller */ 559071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller public void test_uncaughtException_runtimeException() { 560071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller // Our own exception class 561071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller class TestException extends RuntimeException { 562071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller private static final long serialVersionUID = 1L; 563071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller } 564071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller 565071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller final boolean[] passed = new boolean[1]; 566cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath 567071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller ThreadGroup testRoot = new ThreadGroup(initialThreadGroup, "Test other Exception") { 568cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath @Override 569cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath public void uncaughtException(Thread t, Throwable e) { 570cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath if (e instanceof TestException) { 571071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller passed[0] = true; 572cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath } 573071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller // always forward any exception 574071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller super.uncaughtException(t, e); 575cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath } 576cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath }; 577cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath 578071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller final TestException testException = new TestException(); 579071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller Thread thread = new Thread(testRoot, null, "RuntimeException thread") { 580cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath @Override 581cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath public void run() { 582071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller throw testException; 583cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath } 584cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath }; 585cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath thread.start(); 586071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller waitForThreadToDieUninterrupted(thread); 587071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller testThreadDefaultUncaughtExceptionHandler.assertWasCalled(thread, testException); 588cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath testRoot.destroy(); 589cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath assertTrue( 590cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath "Any thread should notify its ThreadGroup about an uncaught exception:" 591071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller + testRoot, passed[0]); 592071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller } 593cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath 594071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller /* 595071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller * Test for method void java.lang.ThreadGroup.uncaughtException(java.lang.Thread, 596071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller * java.lang.Throwable) 597071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller * Test if a handler doesn't pass on the exception to super.uncaughtException that's ok. 598071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller */ 599071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller public void test_uncaughtException_exceptionHandledByHandler() { 600071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller // Our own exception class 601071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller class TestException extends RuntimeException { 602cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath private static final long serialVersionUID = 1L; 603cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath } 604cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath 605071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller ThreadGroup testRoot = new ThreadGroup(initialThreadGroup, "Test other Exception") { 606cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath @Override 607cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath public void uncaughtException(Thread t, Throwable e) { 608071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller // Swallow TestException and always forward any other exception 609071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller if (!(e instanceof TestException)) { 610071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller super.uncaughtException(t, e); 611cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath } 612cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath } 613cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath }; 614cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath 615071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller final TestException testException = new TestException(); 616071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller Thread thread = new Thread(testRoot, null, "RuntimeException thread") { 617cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath @Override 618cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath public void run() { 619071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller throw testException; 620cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath } 621cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath }; 622cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath thread.start(); 623071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller waitForThreadToDieUninterrupted(thread); 624071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller testThreadDefaultUncaughtExceptionHandler.assertWasNotCalled(); 625cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath testRoot.destroy(); 626071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller } 627071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller 628071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller /* 629071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller * Test for method void java.lang.ThreadGroup.uncaughtException(java.lang.Thread, 630071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller * java.lang.Throwable) 631071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller * Tests an exception thrown by the handler itself. 632071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller */ 633071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller public void test_uncaughtException_exceptionInUncaughtException() { 634071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller // Our own uncaught exception classes 635071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller class UncaughtException extends RuntimeException { 636071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller private static final long serialVersionUID = 1L; 637071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller } 638071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller 639071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller ThreadGroup testRoot = new ThreadGroup(initialThreadGroup, 640071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller "Test Exception in uncaught exception") { 641cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath @Override 642cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath public void uncaughtException(Thread t, Throwable e) { 643071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller // This should be no-op according to the spec 644071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller throw new UncaughtException(); 645cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath } 646cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath }; 647cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath 648071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller Thread thread = new Thread(testRoot, null, "no-op thread") { 649cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath @Override 650cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath public void run() { 651071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller throw new RuntimeException(); 652cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath } 653cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath }; 654cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath thread.start(); 655071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller waitForThreadToDieUninterrupted(thread); 656071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller testThreadDefaultUncaughtExceptionHandler.assertWasNotCalled(); 657cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath testRoot.destroy(); 658cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath } 659cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath 660071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller private static ThreadGroup[] allGroups(ThreadGroup parent) { 661cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath int count = parent.activeGroupCount(); 662cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath ThreadGroup[] all = new ThreadGroup[count]; 663cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath parent.enumerate(all, true); 664cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath return all; 665cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath } 666cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath 667071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller private static void asyncBuildRandomTreeUnder(final ThreadGroup aGroup, 668cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath final int depth, final Vector<ThreadGroup> allCreated) { 669cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath if (depth <= 0) { 670cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath return; 671cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath } 672cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath 673cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath final int maxImmediateSubgroups = random(3); 674cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath for (int i = 0; i < maxImmediateSubgroups; i++) { 675cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath final int iClone = i; 676cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath final String name = " Depth = " + depth + ",N = " + iClone 677cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath + ",Vector size at creation: " + allCreated.size(); 678cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath // Use concurrency to maximize chance of exposing concurrency bugs 679cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath // in ThreadGroups 680cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath Thread t = new Thread(aGroup, name) { 681cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath @Override 682cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath public void run() { 683cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath ThreadGroup newGroup = new ThreadGroup(aGroup, name); 684cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath allCreated.addElement(newGroup); 685cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath asyncBuildRandomTreeUnder(newGroup, depth - 1, allCreated); 686cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath } 687cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath }; 688cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath t.start(); 689cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath } 690cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath 691cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath } 692cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath 693071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller private static Vector<ThreadGroup> asyncBuildRandomTreeUnder(final ThreadGroup aGroup, 694cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath final int depth) { 695cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath Vector<ThreadGroup> result = new Vector<ThreadGroup>(); 696cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath asyncBuildRandomTreeUnder(aGroup, depth, result); 697cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath return result; 698cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath 699cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath } 700cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath 701071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller private static ThreadGroup[] groups(ThreadGroup parent) { 702cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath // No API to get the count of immediate children only ? 703cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath int count = parent.activeGroupCount(); 704cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath ThreadGroup[] all = new ThreadGroup[count]; 705cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath parent.enumerate(all, false); 706cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath // Now we may have nulls in the array, we must find the actual size 707cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath int actualSize = 0; 708cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath for (; actualSize < all.length; actualSize++) { 709cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath if (all[actualSize] == null) { 710cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath break; 711cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath } 712cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath } 713cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath ThreadGroup[] result; 714cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath if (actualSize == all.length) { 715cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath result = all; 716cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath } else { 717cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath result = new ThreadGroup[actualSize]; 718cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath System.arraycopy(all, 0, result, 0, actualSize); 719cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath } 720cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath 721cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath return result; 722cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath 723cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath } 724cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath 725071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller private static int random(int max) { 726cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath return 1 + ((new Object()).hashCode() % max); 727cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath } 728cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath 729071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller private static Vector<ThreadGroup> buildRandomTreeUnder(ThreadGroup aGroup, int depth) { 730cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath Vector<ThreadGroup> result = asyncBuildRandomTreeUnder(aGroup, depth); 731cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath while (true) { 732cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath int sizeBefore = result.size(); 733cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath try { 734cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath Thread.sleep(1000); 735cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath int sizeAfter = result.size(); 736cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath // If no activity for a while, we assume async building may be 737cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath // done. 738cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath if (sizeBefore == sizeAfter) { 739cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath // It can only be done if no more threads. Unfortunately we 740cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath // are relying on this API to work as well. 741cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath // If it does not, we may loop forever. 742cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath if (aGroup.activeCount() == 0) { 743cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath break; 744cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath } 745cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath } 746cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath } catch (InterruptedException e) { 747cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath } 748cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath } 749cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath return result; 750cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath 751cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath } 752cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath 753071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller private static boolean arrayIncludes(Object[] array, Object toTest) { 754cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath for (Object element : array) { 755cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath if (element == toTest) { 756cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath return true; 757cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath } 758cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath } 759cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath return false; 760cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath } 761cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath 762071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller private static void waitForThreadToDieUninterrupted(Thread thread) { 763071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller try { 764071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller thread.join(); 765071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller } catch (InterruptedException ie) { 766071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller fail("Should not have been interrupted"); 767071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller } 768cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath } 769cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath 770071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller private static class TestThreadDefaultUncaughtExceptionHandler 771071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller implements Thread.UncaughtExceptionHandler { 772cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath 773071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller private boolean called; 774071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller private Throwable ex; 775071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller private Thread thread; 776071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller 777071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller @Override 778071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller public void uncaughtException(Thread thread, Throwable ex) { 779071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller this.called = true; 780071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller this.thread = thread; 781071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller this.ex = ex; 782071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller } 783071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller 784071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller public void assertWasCalled(Thread thread, Throwable ex) { 785071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller assertTrue(called); 786071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller assertSame(this.thread, thread); 787071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller assertSame(this.ex, ex); 788071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller } 789071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller 790071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller public void assertWasNotCalled() { 791071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller assertFalse(called); 792071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller } 793cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath } 794071ba8eb49cc6ea63dc913aab145076dbeff0049Neil Fuller 795cb318c6f4fe5b0e20099fa85f1b95ccb2d24119fNarayan Kamath} 796