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 org.apache.harmony.tests.java.lang;
19
20import java.lang.Thread.UncaughtExceptionHandler;
21import java.util.Map;
22
23public class ThreadTest extends junit.framework.TestCase {
24
25    static class SimpleThread implements Runnable {
26        int delay;
27
28        public void run() {
29            try {
30                synchronized (this) {
31                    this.notify();
32                    this.wait(delay);
33                }
34            } catch (InterruptedException e) {
35                return;
36            }
37
38        }
39
40        public SimpleThread(int d) {
41            if (d >= 0)
42                delay = d;
43        }
44    }
45
46    static class YieldThread implements Runnable {
47        volatile int delay;
48
49        public void run() {
50            int x = 0;
51            while (true) {
52                ++x;
53            }
54        }
55
56        public YieldThread(int d) {
57            if (d >= 0)
58                delay = d;
59        }
60    }
61
62    static class ResSupThread implements Runnable {
63        Thread parent;
64
65        volatile int checkVal = -1;
66
67        public void run() {
68            try {
69                synchronized (this) {
70                    this.notify();
71                }
72                while (true) {
73                    checkVal++;
74                    zz();
75                    Thread.sleep(100);
76                }
77            } catch (InterruptedException e) {
78                return;
79            } catch (BogusException e) {
80                try {
81                    // Give parent a chance to sleep
82                    Thread.sleep(500);
83                } catch (InterruptedException x) {
84                }
85                parent.interrupt();
86                while (!Thread.currentThread().isInterrupted()) {
87                    // Don't hog the CPU
88                    try {
89                        Thread.sleep(50);
90                    } catch (InterruptedException x) {
91                        // This is what we've been waiting for...don't throw it
92                        // away!
93                        break;
94                    }
95                }
96            }
97        }
98
99        public void zz() throws BogusException {
100        }
101
102        public ResSupThread(Thread t) {
103            parent = t;
104        }
105
106        public synchronized int getCheckVal() {
107            return checkVal;
108        }
109    }
110
111    static class BogusException extends Throwable {
112
113        private static final long serialVersionUID = 1L;
114
115        public BogusException(String s) {
116            super(s);
117        }
118    }
119
120    Thread st, ct, spinner;
121
122    /**
123     * java.lang.Thread#Thread(java.lang.Runnable)
124     */
125    public void test_ConstructorLjava_lang_Runnable() {
126        // Test for method java.lang.Thread(java.lang.Runnable)
127        ct = new Thread(new SimpleThread(10));
128        ct.start();
129    }
130
131    /**
132     * java.lang.Thread#Thread(java.lang.Runnable, java.lang.String)
133     */
134    public void test_ConstructorLjava_lang_RunnableLjava_lang_String() {
135        // Test for method java.lang.Thread(java.lang.Runnable,
136        // java.lang.String)
137        Thread st1 = new Thread(new SimpleThread(1), "SimpleThread1");
138        assertEquals("Constructed thread with incorrect thread name", "SimpleThread1", st1
139                .getName());
140        st1.start();
141    }
142
143    /**
144     * java.lang.Thread#Thread(java.lang.String)
145     */
146    public void test_ConstructorLjava_lang_String() {
147        // Test for method java.lang.Thread(java.lang.String)
148        Thread t = new Thread("Testing");
149        assertEquals("Created tread with incorrect name",
150                "Testing", t.getName());
151        t.start();
152    }
153
154    /**
155     * java.lang.Thread#Thread(java.lang.ThreadGroup, java.lang.Runnable)
156     */
157    public void test_ConstructorLjava_lang_ThreadGroupLjava_lang_Runnable() {
158        // Test for method java.lang.Thread(java.lang.ThreadGroup,
159        // java.lang.Runnable)
160        ThreadGroup tg = new ThreadGroup("Test Group1");
161        st = new Thread(tg, new SimpleThread(1), "SimpleThread2");
162        assertTrue("Returned incorrect thread group", st.getThreadGroup() == tg);
163        st.start();
164        try {
165            st.join();
166        } catch (InterruptedException e) {
167        }
168        tg.destroy();
169    }
170
171    /**
172     * java.lang.Thread#Thread(java.lang.ThreadGroup, java.lang.Runnable,
173     *java.lang.String)
174     */
175    public void test_ConstructorLjava_lang_ThreadGroupLjava_lang_RunnableLjava_lang_String() {
176        // Test for method java.lang.Thread(java.lang.ThreadGroup,
177        // java.lang.Runnable, java.lang.String)
178        ThreadGroup tg = new ThreadGroup("Test Group2");
179        st = new Thread(tg, new SimpleThread(1), "SimpleThread3");
180        assertTrue("Constructed incorrect thread", (st.getThreadGroup() == tg)
181                && st.getName().equals("SimpleThread3"));
182        st.start();
183        try {
184            st.join();
185        } catch (InterruptedException e) {
186        }
187        tg.destroy();
188
189        Runnable r = new Runnable() {
190            public void run() {
191            }
192        };
193
194        ThreadGroup foo = null;
195        try {
196            new Thread(foo = new ThreadGroup("foo"), r, null);
197            // Should not get here
198            fail("Null cannot be accepted as Thread name");
199        } catch (NullPointerException npe) {
200            assertTrue("Null cannot be accepted as Thread name", true);
201            foo.destroy();
202        }
203
204    }
205
206    /**
207     * java.lang.Thread#Thread(java.lang.ThreadGroup, java.lang.String)
208     */
209    public void test_ConstructorLjava_lang_ThreadGroupLjava_lang_String() {
210        // Test for method java.lang.Thread(java.lang.ThreadGroup,
211        // java.lang.String)
212        st = new Thread(new SimpleThread(1), "SimpleThread4");
213        assertEquals("Returned incorrect thread name",
214                "SimpleThread4", st.getName());
215        st.start();
216    }
217
218    /**
219     * java.lang.Thread#activeCount()
220     */
221    public void test_activeCount() {
222        // Test for method int java.lang.Thread.activeCount()
223        Thread t = new Thread(new SimpleThread(10));
224        int active = 0;
225        synchronized (t) {
226            t.start();
227            active = Thread.activeCount();
228        }
229        assertTrue("Incorrect activeCount for current group: " + active, active > 1);
230        try {
231            t.join();
232        } catch (InterruptedException e) {
233        }
234    }
235
236    /**
237     * java.lang.Thread#checkAccess()
238     */
239    public void test_checkAccess() {
240        // Test for method void java.lang.Thread.checkAccess()
241        ThreadGroup tg = new ThreadGroup("Test Group3");
242        try {
243            st = new Thread(tg, new SimpleThread(1), "SimpleThread5");
244            st.checkAccess();
245            assertTrue("CheckAccess passed", true);
246        } catch (SecurityException e) {
247            fail("CheckAccess failed : " + e.getMessage());
248        }
249        st.start();
250        try {
251            st.join();
252        } catch (InterruptedException e) {
253        }
254        tg.destroy();
255    }
256
257    /**
258     * java.lang.Thread#countStackFrames()
259     */
260    @SuppressWarnings("deprecation")
261    public void test_countStackFrames() {
262        /*
263         * Thread.countStackFrames() is unpredictable, so we just test that it
264         * doesn't throw an exception.
265         */
266        Thread.currentThread().countStackFrames();
267    }
268
269    /**
270     * java.lang.Thread#currentThread()
271     */
272    public void test_currentThread() {
273        assertNotNull(Thread.currentThread());
274    }
275
276    public void test_destroy_throwsUnsupportedOperationException() {
277        try {
278            new Thread().destroy();
279            fail();
280        } catch (UnsupportedOperationException expected) {
281        }
282    }
283
284    /**
285     * java.lang.Thread#enumerate(java.lang.Thread[])
286     */
287    public void test_enumerate$Ljava_lang_Thread() {
288        // Test for method int java.lang.Thread.enumerate(java.lang.Thread [])
289        // The test has been updated according to HARMONY-1974 JIRA issue.
290
291        class MyThread extends Thread {
292            MyThread(ThreadGroup tg, String name) {
293                super(tg, name);
294            }
295
296            boolean failed = false;
297            String failMessage = null;
298
299            public void run() {
300                SimpleThread st1 = null;
301                SimpleThread st2 = null;
302                ThreadGroup mytg = null;
303                Thread firstOne = null;
304                Thread secondOne = null;
305                try {
306                    int arrayLength = 10;
307                    Thread[] tarray = new Thread[arrayLength];
308                    st1 = new SimpleThread(-1);
309                    st2 = new SimpleThread(-1);
310                    mytg = new ThreadGroup("jp");
311                    firstOne = new Thread(mytg, st1, "firstOne2");
312                    secondOne = new Thread(mytg, st2, "secondOne1");
313                    int count = Thread.enumerate(tarray);
314                    assertEquals("Incorrect value returned1",
315                            1, count);
316                    synchronized (st1) {
317                        firstOne.start();
318                        try {
319                            st1.wait();
320                        } catch (InterruptedException e) {
321                        }
322                    }
323                    count = Thread.enumerate(tarray);
324                    assertEquals("Incorrect value returned2",
325                            2, count);
326                    synchronized (st2) {
327                        secondOne.start();
328                        try {
329                            st2.wait();
330                        } catch (InterruptedException e) {
331                        }
332                    }
333                    count = Thread.enumerate(tarray);
334                    assertEquals("Incorrect value returned3",
335                            3, count);
336                } catch (junit.framework.AssertionFailedError e) {
337                    failed = true;
338                    failMessage = e.getMessage();
339                } finally {
340                    synchronized (st1) {
341                        firstOne.interrupt();
342                    }
343                    synchronized (st2) {
344                        secondOne.interrupt();
345                    }
346                    try {
347                        firstOne.join();
348                        secondOne.join();
349                    } catch (InterruptedException e) {
350                    }
351                    mytg.destroy();
352                }
353            }
354        }
355        ;
356
357        ThreadGroup tg = new ThreadGroup("tg");
358        MyThread t = new MyThread(tg, "top");
359        t.start();
360        try {
361            t.join();
362        } catch (InterruptedException e) {
363            fail("Unexpected interrupt");
364        } finally {
365            tg.destroy();
366        }
367        assertFalse(t.failMessage, t.failed);
368    }
369
370    /**
371     * java.lang.Thread#getContextClassLoader()
372     */
373    public void test_getContextClassLoader() {
374        // Test for method java.lang.ClassLoader
375        // java.lang.Thread.getContextClassLoader()
376        Thread t = new Thread();
377        assertTrue("Incorrect class loader returned",
378                t.getContextClassLoader() == Thread.currentThread()
379                        .getContextClassLoader());
380        t.start();
381
382    }
383
384    /**
385     * java.lang.Thread#getName()
386     */
387    public void test_getName() {
388        // Test for method java.lang.String java.lang.Thread.getName()
389        st = new Thread(new SimpleThread(1), "SimpleThread6");
390        assertEquals("Returned incorrect thread name",
391                "SimpleThread6", st.getName());
392        st.start();
393    }
394
395    /**
396     * java.lang.Thread#getPriority()
397     */
398    public void test_getPriority() {
399        // Test for method int java.lang.Thread.getPriority()
400        st = new Thread(new SimpleThread(1));
401        st.setPriority(Thread.MAX_PRIORITY);
402        assertTrue("Returned incorrect thread priority",
403                st.getPriority() == Thread.MAX_PRIORITY);
404        st.start();
405    }
406
407    /**
408     * java.lang.Thread#getThreadGroup()
409     */
410    public void test_getThreadGroup() {
411        // Test for method java.lang.ThreadGroup
412        // java.lang.Thread.getThreadGroup()
413        ThreadGroup tg = new ThreadGroup("Test Group4");
414        st = new Thread(tg, new SimpleThread(1), "SimpleThread8");
415        assertTrue("Returned incorrect thread group", st.getThreadGroup() == tg);
416        st.start();
417        try {
418            st.join();
419        } catch (InterruptedException e) {
420        }
421        assertNull("group should be null", st.getThreadGroup());
422        assertNotNull("toString() should not be null", st.toString());
423        tg.destroy();
424
425        final Object lock = new Object();
426        Thread t = new Thread() {
427            @Override
428            public void run() {
429                synchronized (lock) {
430                    lock.notifyAll();
431                }
432            }
433        };
434        synchronized (lock) {
435            t.start();
436            try {
437                lock.wait();
438            } catch (InterruptedException e) {
439            }
440        }
441        int running = 0;
442        while (t.isAlive())
443            running++;
444        ThreadGroup group = t.getThreadGroup();
445        assertNull("ThreadGroup is not null", group);
446    }
447
448    /**
449     * java.lang.Thread#interrupt()
450     */
451    public void test_interrupt() {
452        // Test for method void java.lang.Thread.interrupt()
453        final Object lock = new Object();
454        class ChildThread1 extends Thread {
455            Thread parent;
456
457            boolean sync;
458
459            @Override
460            public void run() {
461                if (sync) {
462                    synchronized (lock) {
463                        lock.notify();
464                        try {
465                            lock.wait();
466                        } catch (InterruptedException e) {
467                        }
468                    }
469                }
470                parent.interrupt();
471            }
472
473            public ChildThread1(Thread p, String name, boolean sync) {
474                super(name);
475                parent = p;
476                this.sync = sync;
477            }
478        }
479        boolean interrupted = false;
480        try {
481            ct = new ChildThread1(Thread.currentThread(), "Interrupt Test1",
482                    false);
483            synchronized (lock) {
484                ct.start();
485                lock.wait();
486            }
487        } catch (InterruptedException e) {
488            interrupted = true;
489        }
490        assertTrue("Failed to Interrupt thread1", interrupted);
491
492        interrupted = false;
493        try {
494            ct = new ChildThread1(Thread.currentThread(), "Interrupt Test2",
495                    true);
496            synchronized (lock) {
497                ct.start();
498                lock.wait();
499                lock.notify();
500            }
501            Thread.sleep(20000);
502        } catch (InterruptedException e) {
503            interrupted = true;
504        }
505        assertTrue("Failed to Interrupt thread2", interrupted);
506
507    }
508
509    /**
510     * java.lang.Thread#interrupted()
511     */
512    public void test_interrupted() {
513        assertFalse("Interrupted returned true for non-interrupted thread", Thread
514                .interrupted());
515        Thread.currentThread().interrupt();
516        assertTrue("Interrupted returned true for non-interrupted thread", Thread.interrupted());
517        assertFalse("Failed to clear interrupted flag", Thread.interrupted());
518    }
519
520    /**
521     * java.lang.Thread#isAlive()
522     */
523    public void test_isAlive() {
524        // Test for method boolean java.lang.Thread.isAlive()
525        SimpleThread simple;
526        st = new Thread(simple = new SimpleThread(500));
527        assertFalse("A thread that wasn't started is alive.", st.isAlive());
528        synchronized (simple) {
529            st.start();
530            try {
531                simple.wait();
532            } catch (InterruptedException e) {
533            }
534        }
535        assertTrue("Started thread returned false", st.isAlive());
536        try {
537            st.join();
538        } catch (InterruptedException e) {
539            fail("Thread did not die");
540        }
541        assertTrue("Stopped thread returned true", !st.isAlive());
542    }
543
544    /**
545     * java.lang.Thread#isDaemon()
546     */
547    public void test_isDaemon() {
548        // Test for method boolean java.lang.Thread.isDaemon()
549        st = new Thread(new SimpleThread(1), "SimpleThread10");
550        assertTrue("Non-Daemon thread returned true", !st.isDaemon());
551        st.setDaemon(true);
552        assertTrue("Daemon thread returned false", st.isDaemon());
553        st.start();
554    }
555
556    /**
557     * java.lang.Thread#isInterrupted()
558     */
559    public void test_isInterrupted() {
560        // Test for method boolean java.lang.Thread.isInterrupted()
561        class SpinThread implements Runnable {
562            public volatile boolean done = false;
563
564            public void run() {
565                while (!Thread.currentThread().isInterrupted())
566                    ;
567                while (!done)
568                    ;
569            }
570        }
571
572        SpinThread spin = new SpinThread();
573        spinner = new Thread(spin);
574        spinner.start();
575        Thread.yield();
576        try {
577            assertTrue("Non-Interrupted thread returned true", !spinner
578                    .isInterrupted());
579            spinner.interrupt();
580            assertTrue("Interrupted thread returned false", spinner
581                    .isInterrupted());
582            spin.done = true;
583        } finally {
584            spinner.interrupt();
585            spin.done = true;
586        }
587    }
588
589    /**
590     * java.lang.Thread#join()
591     */
592    public void test_join() {
593        // Test for method void java.lang.Thread.join()
594        SimpleThread simple;
595        try {
596            st = new Thread(simple = new SimpleThread(100));
597            // cause isAlive() to be compiled by the JIT, as it must be called
598            // within 100ms below.
599            assertTrue("Thread is alive", !st.isAlive());
600            synchronized (simple) {
601                st.start();
602                simple.wait();
603            }
604            st.join();
605        } catch (InterruptedException e) {
606            fail("Join failed ");
607        }
608        assertTrue("Joined thread is still alive", !st.isAlive());
609        boolean result = true;
610        Thread th = new Thread("test");
611        try {
612            th.join();
613        } catch (InterruptedException e) {
614            result = false;
615        }
616        assertTrue("Hung joining a non-started thread", result);
617        th.start();
618    }
619
620    /**
621     * java.lang.Thread#join(long)
622     */
623    public void test_joinJ() {
624        // Test for method void java.lang.Thread.join(long)
625        SimpleThread simple;
626        try {
627            st = new Thread(simple = new SimpleThread(1000), "SimpleThread12");
628            // cause isAlive() to be compiled by the JIT, as it must be called
629            // within 100ms below.
630            assertTrue("Thread is alive", !st.isAlive());
631            synchronized (simple) {
632                st.start();
633                simple.wait();
634            }
635            st.join(10);
636        } catch (InterruptedException e) {
637            fail("Join failed ");
638        }
639        assertTrue("Join failed to timeout", st.isAlive());
640
641        st.interrupt();
642        try {
643            st = new Thread(simple = new SimpleThread(100), "SimpleThread13");
644            synchronized (simple) {
645                st.start();
646                simple.wait();
647            }
648            st.join(1000);
649        } catch (InterruptedException e) {
650            fail("Join failed : " + e.getMessage());
651            return;
652        }
653        assertTrue("Joined thread is still alive", !st.isAlive());
654
655        final Object lock = new Object();
656        final Thread main = Thread.currentThread();
657        Thread killer = new Thread(new Runnable() {
658            public void run() {
659                try {
660                    synchronized (lock) {
661                        lock.notify();
662                    }
663                    Thread.sleep(100);
664                } catch (InterruptedException e) {
665                    return;
666                }
667                main.interrupt();
668            }
669        });
670        boolean result = true;
671        Thread th = new Thread("test");
672        try {
673            synchronized (lock) {
674                killer.start();
675                lock.wait();
676            }
677            th.join(200);
678        } catch (InterruptedException e) {
679            result = false;
680        }
681        killer.interrupt();
682        assertTrue("Hung joining a non-started thread", result);
683        th.start();
684    }
685
686    /**
687     * java.lang.Thread#join(long, int)
688     */
689    public void test_joinJI() throws Exception {
690        // Test for method void java.lang.Thread.join(long, int)
691        SimpleThread simple;
692        st = new Thread(simple = new SimpleThread(1000), "Squawk1");
693        assertTrue("Thread is alive", !st.isAlive());
694        synchronized (simple) {
695            st.start();
696            simple.wait();
697        }
698
699        long firstRead = System.currentTimeMillis();
700        st.join(100, 999999);
701        long secondRead = System.currentTimeMillis();
702        assertTrue("Did not join by appropriate time: " + secondRead + "-"
703                + firstRead + "=" + (secondRead - firstRead), secondRead
704                - firstRead <= 300);
705        assertTrue("Joined thread is not alive", st.isAlive());
706        st.interrupt();
707
708        final Object lock = new Object();
709        final Thread main = Thread.currentThread();
710        Thread killer = new Thread(new Runnable() {
711            public void run() {
712                try {
713                    synchronized (lock) {
714                        lock.notify();
715                    }
716                    Thread.sleep(100);
717                } catch (InterruptedException e) {
718                    return;
719                }
720                main.interrupt();
721            }
722        });
723        boolean result = true;
724        Thread th = new Thread("test");
725        try {
726            synchronized (lock) {
727                killer.start();
728                lock.wait();
729            }
730            th.join(200, 20);
731        } catch (InterruptedException e) {
732            result = false;
733        }
734        killer.interrupt();
735        assertTrue("Hung joining a non-started thread", result);
736        th.start();
737    }
738
739    /**
740     * java.lang.Thread#run()
741     */
742    public void test_run() {
743        // Test for method void java.lang.Thread.run()
744        class RunThread implements Runnable {
745            boolean didThreadRun = false;
746
747            public void run() {
748                didThreadRun = true;
749            }
750        }
751        RunThread rt = new RunThread();
752        Thread t = new Thread(rt);
753        try {
754            t.start();
755            int count = 0;
756            while (!rt.didThreadRun && count < 20) {
757                Thread.sleep(100);
758                count++;
759            }
760            assertTrue("Thread did not run", rt.didThreadRun);
761            t.join();
762        } catch (InterruptedException e) {
763            assertTrue("Joined thread was interrupted", true);
764        }
765        assertTrue("Joined thread is still alive", !t.isAlive());
766    }
767
768    /**
769     * java.lang.Thread#setDaemon(boolean)
770     */
771    public void test_setDaemonZ() {
772        // Test for method void java.lang.Thread.setDaemon(boolean)
773        st = new Thread(new SimpleThread(1), "SimpleThread14");
774        st.setDaemon(true);
775        assertTrue("Failed to set thread as daemon thread", st.isDaemon());
776        st.start();
777    }
778
779    /**
780     * java.lang.Thread#setName(java.lang.String)
781     */
782    public void test_setNameLjava_lang_String() {
783        // Test for method void java.lang.Thread.setName(java.lang.String)
784        st = new Thread(new SimpleThread(1), "SimpleThread15");
785        st.setName("Bogus Name");
786        assertEquals("Failed to set thread name",
787                "Bogus Name", st.getName());
788        try {
789            st.setName(null);
790            fail("Null should not be accepted as a valid name");
791        } catch (NullPointerException e) {
792            // success
793            assertTrue("Null should not be accepted as a valid name", true);
794        }
795        st.start();
796    }
797
798    /**
799     * java.lang.Thread#setPriority(int)
800     */
801    public void test_setPriorityI() {
802        // Test for method void java.lang.Thread.setPriority(int)
803        st = new Thread(new SimpleThread(1));
804        st.setPriority(Thread.MAX_PRIORITY);
805        assertTrue("Failed to set priority",
806                st.getPriority() == Thread.MAX_PRIORITY);
807        st.start();
808    }
809
810    /**
811     * java.lang.Thread#sleep(long)
812     */
813    public void test_sleepJ() {
814        // Test for method void java.lang.Thread.sleep(long)
815
816        // TODO : Test needs enhancing.
817        long stime = 0, ftime = 0;
818        try {
819            stime = System.currentTimeMillis();
820            Thread.sleep(1000);
821            ftime = System.currentTimeMillis();
822        } catch (InterruptedException e) {
823            fail("Unexpected interrupt received");
824        }
825        assertTrue("Failed to sleep long enough", (ftime - stime) >= 800);
826    }
827
828    /**
829     * java.lang.Thread#sleep(long, int)
830     */
831    public void test_sleepJI() {
832        // Test for method void java.lang.Thread.sleep(long, int)
833
834        // TODO : Test needs revisiting.
835        long stime = 0, ftime = 0;
836        try {
837            stime = System.currentTimeMillis();
838            Thread.sleep(1000, 999999);
839            ftime = System.currentTimeMillis();
840        } catch (InterruptedException e) {
841            fail("Unexpected interrupt received");
842        }
843        long result = ftime - stime;
844        assertTrue("Failed to sleep long enough: " + result, result >= 900
845                && result <= 1100);
846    }
847
848    /**
849     * java.lang.Thread#start()
850     */
851    public void test_start() {
852        // Test for method void java.lang.Thread.start()
853        try {
854            ResSupThread t = new ResSupThread(Thread.currentThread());
855            synchronized (t) {
856                ct = new Thread(t, "Interrupt Test4");
857                ct.start();
858                t.wait();
859            }
860            assertTrue("Thread is not running1", ct.isAlive());
861            // Let the child thread get going.
862            int orgval = t.getCheckVal();
863            Thread.sleep(150);
864            assertTrue("Thread is not running2", orgval != t.getCheckVal());
865            ct.interrupt();
866        } catch (InterruptedException e) {
867            fail("Unexpected interrupt occurred");
868        }
869    }
870
871    /**
872     * java.lang.Thread#toString()
873     */
874    public void test_toString() {
875        // Test for method java.lang.String java.lang.Thread.toString()
876        ThreadGroup tg = new ThreadGroup("Test Group5");
877        st = new Thread(tg, new SimpleThread(1), "SimpleThread17");
878        final String stString = st.toString();
879        final String expected = "Thread[SimpleThread17,5,Test Group5]";
880        assertTrue("Returned incorrect string: " + stString + "\t(expecting :"
881                + expected + ")", stString.equals(expected));
882        st.start();
883        try {
884            st.join();
885        } catch (InterruptedException e) {
886        }
887        tg.destroy();
888    }
889
890    /**
891     * java.lang.Thread#getAllStackTraces()
892     */
893    public void test_getAllStackTraces() {
894        Map<Thread, StackTraceElement[]> stMap = Thread.getAllStackTraces();
895        assertNotNull(stMap);
896        //TODO add security-based tests
897    }
898
899    /**
900     * java.lang.Thread#getDefaultUncaughtExceptionHandler
901     * java.lang.Thread#setDefaultUncaughtExceptionHandler
902     */
903    public void test_get_setDefaultUncaughtExceptionHandler() {
904        class Handler implements UncaughtExceptionHandler {
905            public void uncaughtException(Thread thread, Throwable ex) {
906            }
907        }
908
909        final Handler handler = new Handler();
910        Thread.setDefaultUncaughtExceptionHandler(handler);
911        assertSame(handler, Thread.getDefaultUncaughtExceptionHandler());
912
913        Thread.setDefaultUncaughtExceptionHandler(null);
914        assertNull(Thread.getDefaultUncaughtExceptionHandler());
915        //TODO add security-based tests
916    }
917
918    /**
919     * java.lang.Thread#getStackTrace()
920     */
921    public void test_getStackTrace() {
922        StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
923
924        assertNotNull(stackTrace);
925
926        stack_trace_loop:
927        {
928            for (int i = 0; i < stackTrace.length; i++) {
929                StackTraceElement e = stackTrace[i];
930                if (getClass().getName().equals(e.getClassName())) {
931                    if ("test_getStackTrace".equals(e.getMethodName())) {
932                        break stack_trace_loop;
933                    }
934                }
935            }
936            fail("class and method not found in stack trace");
937        }
938
939        //TODO add security-based tests
940    }
941
942    /**
943     * java.lang.Thread#getState()
944     */
945    public void test_getState() {
946        Thread.State state = Thread.currentThread().getState();
947        assertNotNull(state);
948        assertEquals(Thread.State.RUNNABLE, state);
949        //TODO add additional state tests
950    }
951
952    /**
953     * java.lang.Thread#getUncaughtExceptionHandler
954     * java.lang.Thread#setUncaughtExceptionHandler
955     */
956    public void test_get_setUncaughtExceptionHandler() {
957        class Handler implements UncaughtExceptionHandler {
958            public void uncaughtException(Thread thread, Throwable ex) {
959            }
960        }
961
962        final Handler handler = new Handler();
963        Thread.currentThread().setUncaughtExceptionHandler(handler);
964        assertSame(handler, Thread.currentThread().getUncaughtExceptionHandler());
965
966        Thread.currentThread().setUncaughtExceptionHandler(null);
967
968        //TODO add security-based tests
969    }
970
971    /**
972     * java.lang.Thread#getId()
973     */
974    public void test_getId() {
975        assertTrue("current thread's ID is not positive", Thread.currentThread().getId() > 0);
976
977        //check all the current threads for positive IDs
978        Map<Thread, StackTraceElement[]> stMap = Thread.getAllStackTraces();
979        for (Thread thread : stMap.keySet()) {
980            assertTrue("thread's ID is not positive: " + thread.getName(), thread.getId() > 0);
981        }
982    }
983
984
985    @Override
986    protected void tearDown() {
987        try {
988            if (st != null)
989                st.interrupt();
990        } catch (Exception e) {
991        }
992        try {
993            if (spinner != null)
994                spinner.interrupt();
995        } catch (Exception e) {
996        }
997        try {
998            if (ct != null)
999                ct.interrupt();
1000        } catch (Exception e) {
1001        }
1002
1003        try {
1004            spinner = null;
1005            st = null;
1006            ct = null;
1007            System.runFinalization();
1008        } catch (Exception e) {
1009        }
1010    }
1011}
1012