Home | History | Annotate | Download | only in lang
      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 
     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     @SuppressWarnings("DeadThread")
     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 
     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 {
     90         public synchronized void enterLocked() {
     91             boolean b = Thread.holdsLock(this);
     92             assertTrue("Thread should hold lock for object", b);
     93         }
     94 
     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 
    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 
    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 
    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 
    157     private Thread launchFiveSecondDummyThread() {
    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      */
    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 
    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 
    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 
    291         public Counter(boolean isDoYield) {
    292             this.isDoYield = isDoYield;
    293             start();
    294         }
    295 
    296         public void run() {
    297             for(int i = 0; i < 1000; i++) {
    298                 if(isDoYield)
    299                     yield();
    300                 counter ++;
    301             }
    302         }
    303     }
    304 
    305 
    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 
    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")
    391     public void test_stop() {
    392         Thread thread = launchFiveSecondDummyThread();
    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 
    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")
    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")
    444     public void test_suspend() {
    445         Thread thread = launchFiveSecondDummyThread();
    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
    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