1/* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18package libcore.java.lang; 19 20import java.io.ByteArrayOutputStream; 21import java.io.PrintStream; 22import java.util.concurrent.Semaphore; 23import java.util.concurrent.locks.LockSupport; 24import libcore.java.lang.ref.FinalizationTester; 25 26public class OldThreadTest extends junit.framework.TestCase { 27 28 static class SimpleThread implements Runnable { 29 int delay; 30 31 public void run() { 32 try { 33 synchronized (this) { 34 this.notify(); 35 this.wait(delay); 36 } 37 } catch (InterruptedException e) { 38 return; 39 } 40 41 } 42 43 public SimpleThread(int d) { 44 if (d >= 0) 45 delay = d; 46 } 47 } 48 49 public void test_ConstructorLjava_lang_ThreadGroupLjava_lang_RunnableLjava_lang_StringL$L() { 50 ThreadGroup tg = new ThreadGroup("Test Group2"); 51 st = new Thread(tg, new SimpleThread(1), "SimpleThread3", 1); 52 assertTrue("Constructed incorrect thread", (st.getThreadGroup() == tg) 53 && st.getName().equals("SimpleThread3")); 54 st.start(); 55 try { 56 st.join(); 57 } catch (InterruptedException e) { 58 } 59 tg.destroy(); 60 61 try { 62 new Thread(tg, new SimpleThread(1), "SimpleThread3", 63 Integer.MAX_VALUE); 64 fail("StackOverflowError/OutOfMemoryError is not thrown."); 65 } catch(IllegalThreadStateException itse) { 66 //expected 67 } 68 69 } 70 71 public void test_dumpStack() { 72 try { 73 PrintStream savedErr = System.err; 74 ByteArrayOutputStream baos = new ByteArrayOutputStream(); 75 System.setErr(new PrintStream(baos)); 76 Thread.dumpStack(); 77 System.setErr(savedErr); 78 79 String s = new String(baos.toByteArray()); 80 81 assertTrue(s.contains("java.lang.Thread.dumpStack")); 82 83 } catch(Exception e) { 84 fail("Unexpected exception was thrown: " + e.toString()); 85 } 86 } 87 88 class MonitoredClass { 89 public synchronized void enterLocked() { 90 boolean b = Thread.holdsLock(this); 91 assertTrue("Thread should hold lock for object", b); 92 } 93 94 public void enterNonLocked() { 95 boolean b = Thread.holdsLock(this); 96 assertFalse("Thread should not hold lock for object", b); 97 } 98 99 } 100 101 boolean wasInterrupted = false; 102 103 public void test_joinWithSpuriousInterruption() throws InterruptedException { 104 final Thread parker = new Thread() { 105 @Override 106 public void run() { 107 for (int i = 0; i < 10; i++) { 108 // we used to get spurious wakeups upon unparking 109 LockSupport.park(); 110 } 111 } 112 }; 113 Thread unparker = new Thread() { 114 @Override 115 public void run() { 116 for (int i = 0; i < 10; i++) { 117 try { 118 Thread.sleep(100); 119 LockSupport.unpark(parker); 120 } catch (InterruptedException expected) { 121 } 122 } 123 } 124 }; 125 126 long startNanos = System.nanoTime(); 127 parker.start(); 128 unparker.start(); 129 parker.join(500, 500000); 130 long netWaitTime = System.nanoTime() - startNanos; 131 assertTrue("Expected to wait at least 500000000ns, but was " + netWaitTime + "ns", 132 netWaitTime > 500000000); 133 } 134 135 public void test_setContextClassLoader() { 136 ClassLoader pcl = new ClassLoader() {}; 137 st = new Thread(); 138 st.setContextClassLoader(pcl); 139 assertEquals(pcl, st.getContextClassLoader()); 140 141 st.setContextClassLoader(null); 142 assertNull(st.getContextClassLoader()); 143 } 144 145 public void test_setDaemonZ() { 146 st = new Thread(new SimpleThread(5)); 147 st.start(); 148 try { 149 st.setDaemon(false); 150 fail("setDaemon() must throw exception for started thread"); 151 } catch (IllegalThreadStateException ex) { 152 // We expect this one. 153 } 154 } 155 156 private Thread launchFiveSecondDummyThread() { 157 Thread thread = new Thread() { 158 public void run() { 159 try { 160 Thread.sleep(5000); 161 } catch (InterruptedException e) { 162 // Ignore 163 } 164 } 165 }; 166 167 thread.start(); 168 169 return thread; 170 } 171 172 /** 173 * java.lang.Thread#sleep(long) 174 */ 175 public void test_sleepJ() { 176 // Note: Not too much we can test here that can be reliably measured. 177 178 // Check that basic behavior is about right (with some tolerance) 179 long stime = System.currentTimeMillis(); 180 181 try { 182 Thread.sleep(1000); 183 } catch (InterruptedException e) { 184 fail("Unexpected InterruptedException was thrown"); 185 } 186 187 long ftime = System.currentTimeMillis(); 188 189 assertTrue("Failed to sleep long enough", (ftime - stime) >= 500); 190 assertTrue("Failed to wake up early enough", (ftime - stime) <= 1500); 191 192 // Check that interrupt works 193 st = new Thread() { 194 public void run() { 195 try { 196 sleep(10000); 197 } catch(InterruptedException ie) { 198 wasInterrupted = true; 199 } 200 } 201 }; 202 203 st.start(); 204 205 try { 206 Thread.sleep(5000); 207 } catch(InterruptedException e) { 208 fail("Unexpected InterruptedException was thrown"); 209 } 210 211 st.interrupt(); 212 213 try { 214 Thread.sleep(5000); 215 } catch(InterruptedException e) { 216 fail("Unexpected InterruptedException was thrown"); 217 } 218 219 assertTrue(wasInterrupted); 220 } 221 222 public void test_sleepJI() { 223 // Note: Not too much we can test here that can be reliably measured. 224 225 // Check that basic behavior is about right (with some tolerance) 226 long stime = System.currentTimeMillis(); 227 228 try { 229 Thread.sleep(1000, 99999); 230 } catch (InterruptedException e) { 231 fail("Unexpected InterruptedException was thrown"); 232 } 233 234 long ftime = System.currentTimeMillis(); 235 236 assertTrue("Failed to sleep long enough", (ftime - stime) >= 500); 237 assertTrue("Failed to wake up early enough", (ftime - stime) <= 1500); 238 239 // Check that interrupt works 240 st = new Thread() { 241 public void run() { 242 try { 243 sleep(10000, 99999); 244 } catch(InterruptedException ie) { 245 wasInterrupted = true; 246 } 247 } 248 }; 249 250 st.start(); 251 252 try { 253 Thread.sleep(5000, 99999); 254 } catch(InterruptedException e) { 255 fail("Unexpected InterruptedException was thrown"); 256 } 257 258 st.interrupt(); 259 260 try { 261 Thread.sleep(5000); 262 } catch(InterruptedException e) { 263 fail("Unexpected InterruptedException was thrown"); 264 } 265 266 assertTrue(wasInterrupted); 267 } 268 269 public void test_yield() { 270 271 Counter [] countersNotYeld = new Counter[10]; 272 273 for(int i = 0; i < 10; i++) { 274 countersNotYeld[i] = new Counter(false); 275 } 276 Counter countersYeld = new Counter(true); 277 try { 278 Thread.sleep(11000); 279 } catch(InterruptedException ie) {} 280 281 for(Counter c:countersNotYeld) { 282 assertTrue(countersYeld.counter == c.counter); 283 } 284 } 285 286 class Counter extends Thread { 287 public int counter = 0; 288 boolean isDoYield = false; 289 290 public Counter(boolean isDoYield) { 291 this.isDoYield = isDoYield; 292 start(); 293 } 294 295 public void run() { 296 for(int i = 0; i < 10000; i++) { 297 if(isDoYield) 298 yield(); 299 counter ++; 300 } 301 } 302 } 303 304 305 public void test_getState() throws InterruptedException { 306 Thread.State state = Thread.currentThread().getState(); 307 assertNotNull(state); 308 assertEquals(Thread.State.RUNNABLE, state); 309 310 run = true; 311 final Semaphore sem = new Semaphore(0); 312 final Object lock = new Object(); 313 Thread th = new Thread() { 314 @Override 315 public void run() { 316 while (!sem.hasQueuedThreads()) {} 317 sem.release(); 318 319 // RUNNABLE 320 while (run) {} 321 322 try { 323 // WAITING 324 sem.acquire(); 325 } catch (InterruptedException e) { 326 fail("InterruptedException was thrown."); 327 } 328 329 // BLOCKED 330 synchronized (lock) { 331 lock.equals(new Object()); 332 } 333 synchronized (lock) { 334 try { 335 sem.release(); 336 337 // TIMED_WAITING 338 lock.wait(Long.MAX_VALUE); 339 } catch (InterruptedException e) { 340 // expected 341 } 342 } 343 344 // TERMINATED upon return 345 } 346 }; 347 assertEquals(Thread.State.NEW, th.getState()); 348 th.start(); 349 sem.acquire(); 350 assertEquals(Thread.State.RUNNABLE, th.getState()); 351 run = false; 352 353 Thread.sleep(200); 354 355 assertEquals(Thread.State.WAITING, th.getState()); 356 synchronized (lock) { 357 sem.release(); 358 long start = System.currentTimeMillis(); 359 while(start + 1000 > System.currentTimeMillis()) {} 360 assertEquals(Thread.State.BLOCKED, th.getState()); 361 } 362 363 sem.acquire(); 364 365 synchronized (lock) { 366 assertEquals(Thread.State.TIMED_WAITING, th.getState()); 367 th.interrupt(); 368 } 369 370 th.join(1000); 371 assertEquals(Thread.State.TERMINATED, th.getState()); 372 } 373 volatile boolean run; 374 375 public void test_holdsLock() { 376 MonitoredClass monitor = new MonitoredClass(); 377 378 monitor.enterLocked(); 379 monitor.enterNonLocked(); 380 381 try { 382 Thread.holdsLock(null); 383 fail("NullPointerException was not thrown."); 384 } catch(NullPointerException npe) { 385 //expected 386 } 387 } 388 389 @SuppressWarnings("deprecation") 390 public void test_stop() { 391 Thread thread = launchFiveSecondDummyThread(); 392 393 try { 394 Thread.sleep(1000); 395 } catch (InterruptedException e) { 396 // Ignore 397 } 398 399 try { 400 thread.stop(); 401 fail(); 402 } catch (UnsupportedOperationException expected) { 403 } 404 } 405 406 public void test_start() { 407 Thread thr = new Thread(); 408 thr.start(); 409 try { 410 thr.start(); 411 } catch(IllegalThreadStateException itse){ 412 //expected 413 } 414 } 415 416 @SuppressWarnings("deprecation") 417 public void test_stopLjava_lang_Throwable_subtest0() { 418 Thread thread = new Thread() { 419 public void run() { 420 try { 421 Thread.sleep(5000); 422 } catch (InterruptedException e) { 423 // Ignore 424 } 425 } 426 }; 427 428 thread.start(); 429 try { 430 Thread.sleep(1000); 431 } catch (InterruptedException e) { 432 // Ignore 433 } 434 435 try { 436 thread.stop(new Exception("Oops!")); 437 fail(); 438 } catch (UnsupportedOperationException expected) { 439 } 440 } 441 442 @SuppressWarnings("deprecation") 443 public void test_suspend() { 444 Thread thread = launchFiveSecondDummyThread(); 445 446 try { 447 Thread.sleep(1000); 448 } catch (InterruptedException e) { 449 // Ignore 450 } 451 452 try { 453 thread.suspend(); 454 fail(); 455 } catch (UnsupportedOperationException expected) { 456 } 457 } 458 459 Thread st, ct, spinner; 460 461 @Override 462 protected void tearDown() { 463 try { 464 if (st != null) 465 st.interrupt(); 466 } catch (Exception e) { 467 } 468 try { 469 if (spinner != null) 470 spinner.interrupt(); 471 } catch (Exception e) { 472 } 473 try { 474 if (ct != null) 475 ct.interrupt(); 476 } catch (Exception e) { 477 } 478 479 try { 480 spinner = null; 481 st = null; 482 ct = null; 483 FinalizationTester.induceFinalization(); 484 } catch (Exception e) { 485 } 486 } 487} 488