1be013ce620f6d3bd24f7f0b631a36f70197ac3e3Jesse Wilson/* 2be013ce620f6d3bd24f7f0b631a36f70197ac3e3Jesse Wilson * Copyright (C) 2010 The Android Open Source Project 3be013ce620f6d3bd24f7f0b631a36f70197ac3e3Jesse Wilson * 4be013ce620f6d3bd24f7f0b631a36f70197ac3e3Jesse Wilson * Licensed under the Apache License, Version 2.0 (the "License"); 5be013ce620f6d3bd24f7f0b631a36f70197ac3e3Jesse Wilson * you may not use this file except in compliance with the License. 6be013ce620f6d3bd24f7f0b631a36f70197ac3e3Jesse Wilson * You may obtain a copy of the License at 7be013ce620f6d3bd24f7f0b631a36f70197ac3e3Jesse Wilson * 8be013ce620f6d3bd24f7f0b631a36f70197ac3e3Jesse Wilson * http://www.apache.org/licenses/LICENSE-2.0 9be013ce620f6d3bd24f7f0b631a36f70197ac3e3Jesse Wilson * 10be013ce620f6d3bd24f7f0b631a36f70197ac3e3Jesse Wilson * Unless required by applicable law or agreed to in writing, software 11be013ce620f6d3bd24f7f0b631a36f70197ac3e3Jesse Wilson * distributed under the License is distributed on an "AS IS" BASIS, 12be013ce620f6d3bd24f7f0b631a36f70197ac3e3Jesse Wilson * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13be013ce620f6d3bd24f7f0b631a36f70197ac3e3Jesse Wilson * See the License for the specific language governing permissions and 14be013ce620f6d3bd24f7f0b631a36f70197ac3e3Jesse Wilson * limitations under the License. 15be013ce620f6d3bd24f7f0b631a36f70197ac3e3Jesse Wilson */ 16be013ce620f6d3bd24f7f0b631a36f70197ac3e3Jesse Wilson 17be013ce620f6d3bd24f7f0b631a36f70197ac3e3Jesse Wilsonpackage libcore.java.lang; 18be013ce620f6d3bd24f7f0b631a36f70197ac3e3Jesse Wilson 19be013ce620f6d3bd24f7f0b631a36f70197ac3e3Jesse Wilsonimport java.util.concurrent.atomic.AtomicInteger; 200647bfed6eda99ad77b2dfe8e3696e3fabfaf3ccJesse Wilsonimport junit.framework.Assert; 21be013ce620f6d3bd24f7f0b631a36f70197ac3e3Jesse Wilsonimport junit.framework.TestCase; 221a9cff8f68deffd618c5cba1f22f0fb0e396e067Jesse Wilsonimport libcore.java.lang.ref.FinalizationTester; 23be013ce620f6d3bd24f7f0b631a36f70197ac3e3Jesse Wilson 24be013ce620f6d3bd24f7f0b631a36f70197ac3e3Jesse Wilsonpublic final class ThreadTest extends TestCase { 25be013ce620f6d3bd24f7f0b631a36f70197ac3e3Jesse Wilson 260647bfed6eda99ad77b2dfe8e3696e3fabfaf3ccJesse Wilson /** 270647bfed6eda99ad77b2dfe8e3696e3fabfaf3ccJesse Wilson * getContextClassLoader returned a non-application class loader. 280647bfed6eda99ad77b2dfe8e3696e3fabfaf3ccJesse Wilson * http://code.google.com/p/android/issues/detail?id=5697 290647bfed6eda99ad77b2dfe8e3696e3fabfaf3ccJesse Wilson */ 300647bfed6eda99ad77b2dfe8e3696e3fabfaf3ccJesse Wilson public void testJavaContextClassLoader() throws Exception { 310647bfed6eda99ad77b2dfe8e3696e3fabfaf3ccJesse Wilson Assert.assertNotNull("Must have a Java context ClassLoader", 320647bfed6eda99ad77b2dfe8e3696e3fabfaf3ccJesse Wilson Thread.currentThread().getContextClassLoader()); 330647bfed6eda99ad77b2dfe8e3696e3fabfaf3ccJesse Wilson } 340647bfed6eda99ad77b2dfe8e3696e3fabfaf3ccJesse Wilson 35be013ce620f6d3bd24f7f0b631a36f70197ac3e3Jesse Wilson public void testLeakingStartedThreads() { 36be013ce620f6d3bd24f7f0b631a36f70197ac3e3Jesse Wilson final AtomicInteger finalizedThreadsCount = new AtomicInteger(); 37be013ce620f6d3bd24f7f0b631a36f70197ac3e3Jesse Wilson for (int i = 0; true; i++) { 38be013ce620f6d3bd24f7f0b631a36f70197ac3e3Jesse Wilson try { 39be013ce620f6d3bd24f7f0b631a36f70197ac3e3Jesse Wilson newThread(finalizedThreadsCount, 1024 << i).start(); 40be013ce620f6d3bd24f7f0b631a36f70197ac3e3Jesse Wilson } catch (OutOfMemoryError expected) { 41be013ce620f6d3bd24f7f0b631a36f70197ac3e3Jesse Wilson break; 42be013ce620f6d3bd24f7f0b631a36f70197ac3e3Jesse Wilson } 43be013ce620f6d3bd24f7f0b631a36f70197ac3e3Jesse Wilson } 441a9cff8f68deffd618c5cba1f22f0fb0e396e067Jesse Wilson FinalizationTester.induceFinalization(); 45be013ce620f6d3bd24f7f0b631a36f70197ac3e3Jesse Wilson assertTrue("Started threads were never finalized!", finalizedThreadsCount.get() > 0); 46be013ce620f6d3bd24f7f0b631a36f70197ac3e3Jesse Wilson } 47be013ce620f6d3bd24f7f0b631a36f70197ac3e3Jesse Wilson 48be013ce620f6d3bd24f7f0b631a36f70197ac3e3Jesse Wilson public void testLeakingUnstartedThreads() { 49be013ce620f6d3bd24f7f0b631a36f70197ac3e3Jesse Wilson final AtomicInteger finalizedThreadsCount = new AtomicInteger(); 50be013ce620f6d3bd24f7f0b631a36f70197ac3e3Jesse Wilson for (int i = 0; true; i++) { 51be013ce620f6d3bd24f7f0b631a36f70197ac3e3Jesse Wilson try { 52be013ce620f6d3bd24f7f0b631a36f70197ac3e3Jesse Wilson newThread(finalizedThreadsCount, 1024 << i); 53be013ce620f6d3bd24f7f0b631a36f70197ac3e3Jesse Wilson } catch (OutOfMemoryError expected) { 54be013ce620f6d3bd24f7f0b631a36f70197ac3e3Jesse Wilson break; 55be013ce620f6d3bd24f7f0b631a36f70197ac3e3Jesse Wilson } 56be013ce620f6d3bd24f7f0b631a36f70197ac3e3Jesse Wilson } 571a9cff8f68deffd618c5cba1f22f0fb0e396e067Jesse Wilson FinalizationTester.induceFinalization(); 58be013ce620f6d3bd24f7f0b631a36f70197ac3e3Jesse Wilson assertTrue("Unstarted threads were never finalized!", finalizedThreadsCount.get() > 0); 59be013ce620f6d3bd24f7f0b631a36f70197ac3e3Jesse Wilson } 60be013ce620f6d3bd24f7f0b631a36f70197ac3e3Jesse Wilson 61b20185245f53374b3a86705ac152fd88e4bddec5jeffhao public void testThreadSleep() throws Exception { 62b5a43a8ad530a60469bf9244a157079c93c07c8bBrian Carlstrom int millis = 1000; 63b5a43a8ad530a60469bf9244a157079c93c07c8bBrian Carlstrom long start = System.currentTimeMillis(); 64b20185245f53374b3a86705ac152fd88e4bddec5jeffhao 65b5a43a8ad530a60469bf9244a157079c93c07c8bBrian Carlstrom Thread.sleep(millis); 66b20185245f53374b3a86705ac152fd88e4bddec5jeffhao 67b5a43a8ad530a60469bf9244a157079c93c07c8bBrian Carlstrom long elapsed = System.currentTimeMillis() - start; 68b5a43a8ad530a60469bf9244a157079c93c07c8bBrian Carlstrom long offBy = Math.abs(elapsed - millis); 69b20185245f53374b3a86705ac152fd88e4bddec5jeffhao 70b5a43a8ad530a60469bf9244a157079c93c07c8bBrian Carlstrom assertTrue("Actual sleep off by " + offBy + " ms", offBy <= 250); 71b5a43a8ad530a60469bf9244a157079c93c07c8bBrian Carlstrom } 72b5a43a8ad530a60469bf9244a157079c93c07c8bBrian Carlstrom 73b5a43a8ad530a60469bf9244a157079c93c07c8bBrian Carlstrom public void testThreadInterrupted() throws Exception { 74b5a43a8ad530a60469bf9244a157079c93c07c8bBrian Carlstrom Thread.currentThread().interrupt(); 75b5a43a8ad530a60469bf9244a157079c93c07c8bBrian Carlstrom try { 76b5a43a8ad530a60469bf9244a157079c93c07c8bBrian Carlstrom Thread.sleep(0); 77b5a43a8ad530a60469bf9244a157079c93c07c8bBrian Carlstrom fail(); 78b5a43a8ad530a60469bf9244a157079c93c07c8bBrian Carlstrom } catch (InterruptedException e) { 79b5a43a8ad530a60469bf9244a157079c93c07c8bBrian Carlstrom assertFalse(Thread.currentThread().isInterrupted()); 80b5a43a8ad530a60469bf9244a157079c93c07c8bBrian Carlstrom } 81b5a43a8ad530a60469bf9244a157079c93c07c8bBrian Carlstrom } 82b5a43a8ad530a60469bf9244a157079c93c07c8bBrian Carlstrom 83b5a43a8ad530a60469bf9244a157079c93c07c8bBrian Carlstrom public void testThreadSleepIllegalArguments() throws Exception { 84b5a43a8ad530a60469bf9244a157079c93c07c8bBrian Carlstrom 85b5a43a8ad530a60469bf9244a157079c93c07c8bBrian Carlstrom try { 86b5a43a8ad530a60469bf9244a157079c93c07c8bBrian Carlstrom Thread.sleep(-1); 87b5a43a8ad530a60469bf9244a157079c93c07c8bBrian Carlstrom fail(); 88b5a43a8ad530a60469bf9244a157079c93c07c8bBrian Carlstrom } catch (IllegalArgumentException expected) { 89b5a43a8ad530a60469bf9244a157079c93c07c8bBrian Carlstrom } 90b5a43a8ad530a60469bf9244a157079c93c07c8bBrian Carlstrom 91b5a43a8ad530a60469bf9244a157079c93c07c8bBrian Carlstrom try { 92b5a43a8ad530a60469bf9244a157079c93c07c8bBrian Carlstrom Thread.sleep(0, -1); 93b5a43a8ad530a60469bf9244a157079c93c07c8bBrian Carlstrom fail(); 94b5a43a8ad530a60469bf9244a157079c93c07c8bBrian Carlstrom } catch (IllegalArgumentException expected) { 95b5a43a8ad530a60469bf9244a157079c93c07c8bBrian Carlstrom } 96b5a43a8ad530a60469bf9244a157079c93c07c8bBrian Carlstrom 97b5a43a8ad530a60469bf9244a157079c93c07c8bBrian Carlstrom try { 98b5a43a8ad530a60469bf9244a157079c93c07c8bBrian Carlstrom Thread.sleep(0, 1000000); 99b5a43a8ad530a60469bf9244a157079c93c07c8bBrian Carlstrom fail(); 100b5a43a8ad530a60469bf9244a157079c93c07c8bBrian Carlstrom } catch (IllegalArgumentException expected) { 101b5a43a8ad530a60469bf9244a157079c93c07c8bBrian Carlstrom } 102b20185245f53374b3a86705ac152fd88e4bddec5jeffhao } 103b20185245f53374b3a86705ac152fd88e4bddec5jeffhao 104b20185245f53374b3a86705ac152fd88e4bddec5jeffhao public void testThreadWakeup() throws Exception { 105b20185245f53374b3a86705ac152fd88e4bddec5jeffhao WakeupTestThread t1 = new WakeupTestThread(); 106b20185245f53374b3a86705ac152fd88e4bddec5jeffhao WakeupTestThread t2 = new WakeupTestThread(); 107b20185245f53374b3a86705ac152fd88e4bddec5jeffhao 108b20185245f53374b3a86705ac152fd88e4bddec5jeffhao t1.start(); 109b20185245f53374b3a86705ac152fd88e4bddec5jeffhao t2.start(); 110b20185245f53374b3a86705ac152fd88e4bddec5jeffhao assertTrue("Threads already finished", !t1.done && !t2.done); 111b20185245f53374b3a86705ac152fd88e4bddec5jeffhao 112b20185245f53374b3a86705ac152fd88e4bddec5jeffhao t1.interrupt(); 113b20185245f53374b3a86705ac152fd88e4bddec5jeffhao t2.interrupt(); 114b20185245f53374b3a86705ac152fd88e4bddec5jeffhao 115b20185245f53374b3a86705ac152fd88e4bddec5jeffhao Thread.sleep(1000); 116b20185245f53374b3a86705ac152fd88e4bddec5jeffhao assertTrue("Threads did not finish", t1.done && t2.done); 117b20185245f53374b3a86705ac152fd88e4bddec5jeffhao } 118b20185245f53374b3a86705ac152fd88e4bddec5jeffhao 119b20185245f53374b3a86705ac152fd88e4bddec5jeffhao public void testContextClassLoaderIsNotNull() { 120b20185245f53374b3a86705ac152fd88e4bddec5jeffhao assertNotNull(Thread.currentThread().getContextClassLoader()); 121b20185245f53374b3a86705ac152fd88e4bddec5jeffhao } 122b20185245f53374b3a86705ac152fd88e4bddec5jeffhao 123b20185245f53374b3a86705ac152fd88e4bddec5jeffhao public void testContextClassLoaderIsInherited() { 124b20185245f53374b3a86705ac152fd88e4bddec5jeffhao Thread other = new Thread(); 125b20185245f53374b3a86705ac152fd88e4bddec5jeffhao assertSame(Thread.currentThread().getContextClassLoader(), other.getContextClassLoader()); 126be013ce620f6d3bd24f7f0b631a36f70197ac3e3Jesse Wilson } 1270647bfed6eda99ad77b2dfe8e3696e3fabfaf3ccJesse Wilson 1280647bfed6eda99ad77b2dfe8e3696e3fabfaf3ccJesse Wilson /** 1290647bfed6eda99ad77b2dfe8e3696e3fabfaf3ccJesse Wilson * Thread.getStackTrace() is broken. http://b/1252043 1300647bfed6eda99ad77b2dfe8e3696e3fabfaf3ccJesse Wilson */ 1310647bfed6eda99ad77b2dfe8e3696e3fabfaf3ccJesse Wilson public void testGetStackTrace() throws Exception { 1320647bfed6eda99ad77b2dfe8e3696e3fabfaf3ccJesse Wilson Thread t1 = new Thread("t1") { 1330647bfed6eda99ad77b2dfe8e3696e3fabfaf3ccJesse Wilson @Override public void run() { 1340647bfed6eda99ad77b2dfe8e3696e3fabfaf3ccJesse Wilson doSomething(); 1350647bfed6eda99ad77b2dfe8e3696e3fabfaf3ccJesse Wilson } 1360647bfed6eda99ad77b2dfe8e3696e3fabfaf3ccJesse Wilson public void doSomething() { 1370647bfed6eda99ad77b2dfe8e3696e3fabfaf3ccJesse Wilson for (int i = 0; i < 20;) { 1380647bfed6eda99ad77b2dfe8e3696e3fabfaf3ccJesse Wilson try { 1390647bfed6eda99ad77b2dfe8e3696e3fabfaf3ccJesse Wilson Thread.sleep(100); 1400647bfed6eda99ad77b2dfe8e3696e3fabfaf3ccJesse Wilson } catch (InterruptedException ignored) { 1410647bfed6eda99ad77b2dfe8e3696e3fabfaf3ccJesse Wilson } 1420647bfed6eda99ad77b2dfe8e3696e3fabfaf3ccJesse Wilson } 1430647bfed6eda99ad77b2dfe8e3696e3fabfaf3ccJesse Wilson } 1440647bfed6eda99ad77b2dfe8e3696e3fabfaf3ccJesse Wilson }; 1450647bfed6eda99ad77b2dfe8e3696e3fabfaf3ccJesse Wilson t1.start(); 1460647bfed6eda99ad77b2dfe8e3696e3fabfaf3ccJesse Wilson Thread.sleep(1000); 1470647bfed6eda99ad77b2dfe8e3696e3fabfaf3ccJesse Wilson StackTraceElement[] traces = t1.getStackTrace(); 1480647bfed6eda99ad77b2dfe8e3696e3fabfaf3ccJesse Wilson StackTraceElement trace = traces[traces.length - 2]; 1490647bfed6eda99ad77b2dfe8e3696e3fabfaf3ccJesse Wilson 1500647bfed6eda99ad77b2dfe8e3696e3fabfaf3ccJesse Wilson // Expect to find MyThread.doSomething in the trace 1510647bfed6eda99ad77b2dfe8e3696e3fabfaf3ccJesse Wilson assertTrue(trace.getClassName().contains("ThreadTest") 1520647bfed6eda99ad77b2dfe8e3696e3fabfaf3ccJesse Wilson && trace.getMethodName().equals("doSomething")); 1530647bfed6eda99ad77b2dfe8e3696e3fabfaf3ccJesse Wilson } 1540647bfed6eda99ad77b2dfe8e3696e3fabfaf3ccJesse Wilson 1550647bfed6eda99ad77b2dfe8e3696e3fabfaf3ccJesse Wilson public void testGetAllStackTracesIncludesAllGroups() throws Exception { 1560647bfed6eda99ad77b2dfe8e3696e3fabfaf3ccJesse Wilson final AtomicInteger visibleTraces = new AtomicInteger(); 1570647bfed6eda99ad77b2dfe8e3696e3fabfaf3ccJesse Wilson ThreadGroup group = new ThreadGroup("1"); 1580647bfed6eda99ad77b2dfe8e3696e3fabfaf3ccJesse Wilson Thread t2 = new Thread(group, "t2") { 1590647bfed6eda99ad77b2dfe8e3696e3fabfaf3ccJesse Wilson @Override public void run() { 1600647bfed6eda99ad77b2dfe8e3696e3fabfaf3ccJesse Wilson visibleTraces.set(Thread.getAllStackTraces().size()); 1610647bfed6eda99ad77b2dfe8e3696e3fabfaf3ccJesse Wilson } 1620647bfed6eda99ad77b2dfe8e3696e3fabfaf3ccJesse Wilson }; 1630647bfed6eda99ad77b2dfe8e3696e3fabfaf3ccJesse Wilson t2.start(); 1640647bfed6eda99ad77b2dfe8e3696e3fabfaf3ccJesse Wilson t2.join(); 1650647bfed6eda99ad77b2dfe8e3696e3fabfaf3ccJesse Wilson 1660647bfed6eda99ad77b2dfe8e3696e3fabfaf3ccJesse Wilson // Expect to see the traces of all threads (not just t2) 1670647bfed6eda99ad77b2dfe8e3696e3fabfaf3ccJesse Wilson assertTrue("Must have traces for all threads", visibleTraces.get() > 1); 1680647bfed6eda99ad77b2dfe8e3696e3fabfaf3ccJesse Wilson } 169b20185245f53374b3a86705ac152fd88e4bddec5jeffhao 170b20185245f53374b3a86705ac152fd88e4bddec5jeffhao private Thread newThread(final AtomicInteger finalizedThreadsCount, final int size) { 171b20185245f53374b3a86705ac152fd88e4bddec5jeffhao return new Thread() { 172b20185245f53374b3a86705ac152fd88e4bddec5jeffhao long[] memoryPressure = new long[size]; 173b20185245f53374b3a86705ac152fd88e4bddec5jeffhao @Override protected void finalize() throws Throwable { 174b20185245f53374b3a86705ac152fd88e4bddec5jeffhao super.finalize(); 175b20185245f53374b3a86705ac152fd88e4bddec5jeffhao finalizedThreadsCount.incrementAndGet(); 176b20185245f53374b3a86705ac152fd88e4bddec5jeffhao } 177b20185245f53374b3a86705ac152fd88e4bddec5jeffhao }; 178b20185245f53374b3a86705ac152fd88e4bddec5jeffhao } 179b20185245f53374b3a86705ac152fd88e4bddec5jeffhao 180b20185245f53374b3a86705ac152fd88e4bddec5jeffhao private class WakeupTestThread extends Thread { 181b20185245f53374b3a86705ac152fd88e4bddec5jeffhao public boolean done; 182b20185245f53374b3a86705ac152fd88e4bddec5jeffhao 183b20185245f53374b3a86705ac152fd88e4bddec5jeffhao public void run() { 184b20185245f53374b3a86705ac152fd88e4bddec5jeffhao done = false; 185b20185245f53374b3a86705ac152fd88e4bddec5jeffhao 186b20185245f53374b3a86705ac152fd88e4bddec5jeffhao // Sleep for a while (1 min) 187b20185245f53374b3a86705ac152fd88e4bddec5jeffhao try { 188b20185245f53374b3a86705ac152fd88e4bddec5jeffhao Thread.sleep(60000); 189c3d53e68cbf91fb4c16abb88f8bf8a8e4be4d706Jesse Wilson } catch (InterruptedException ignored) { 190b20185245f53374b3a86705ac152fd88e4bddec5jeffhao } 191b20185245f53374b3a86705ac152fd88e4bddec5jeffhao 192b20185245f53374b3a86705ac152fd88e4bddec5jeffhao done = true; 193b20185245f53374b3a86705ac152fd88e4bddec5jeffhao } 194b20185245f53374b3a86705ac152fd88e4bddec5jeffhao } 195be013ce620f6d3bd24f7f0b631a36f70197ac3e3Jesse Wilson} 196