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