ThreadTest.java revision 6c9ab280e2cbb1407ad67ccbb0a0464c571fde63
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.luni.tests.java.lang;
19
20import java.io.ByteArrayOutputStream;
21import java.io.PrintStream;
22import java.lang.Thread.UncaughtExceptionHandler;
23import java.security.Permission;
24import java.util.Map;
25import java.util.concurrent.Semaphore;
26import java.util.concurrent.locks.LockSupport;
27import java.util.concurrent.atomic.AtomicReference;
28
29import dalvik.annotation.AndroidOnly;
30import dalvik.annotation.TestLevel;
31import dalvik.annotation.TestTargetClass;
32import dalvik.annotation.TestTargetNew;
33import dalvik.annotation.TestTargets;
34
35@TestTargetClass(Thread.class)
36public class ThreadTest extends junit.framework.TestCase {
37
38    int counter = 0;
39
40    static class SimpleThread implements Runnable {
41        int delay;
42
43        public void run() {
44            try {
45                synchronized (this) {
46                    this.notify();
47                    this.wait(delay);
48                }
49            } catch (InterruptedException e) {
50                return;
51            }
52
53        }
54
55        public SimpleThread(int d) {
56            if (d >= 0)
57                delay = d;
58        }
59    }
60
61    static class YieldThread implements Runnable {
62        volatile int delay;
63
64        public void run() {
65            int x = 0;
66            while (true) {
67                ++x;
68            }
69        }
70
71        public YieldThread(int d) {
72            if (d >= 0)
73                delay = d;
74        }
75    }
76
77    static class ResSupThread implements Runnable {
78        Thread parent;
79
80        volatile int checkVal = -1;
81
82        public void run() {
83            try {
84                synchronized (this) {
85                    this.notify();
86                }
87                while (true) {
88                    checkVal++;
89                    zz();
90                    Thread.sleep(100);
91                }
92            } catch (InterruptedException e) {
93                return;
94            } catch (BogusException e) {
95                try {
96                    // Give parent a chance to sleep
97                    Thread.sleep(500);
98                } catch (InterruptedException x) {
99                }
100                parent.interrupt();
101                while (!Thread.currentThread().isInterrupted()) {
102                    // Don't hog the CPU
103                    try {
104                        Thread.sleep(50);
105                    } catch (InterruptedException x) {
106                        // This is what we've been waiting for...don't throw it
107                        // away!
108                        break;
109                    }
110                }
111            }
112        }
113
114        public void zz() throws BogusException {
115        }
116
117        public ResSupThread(Thread t) {
118            parent = t;
119        }
120
121        public synchronized int getCheckVal() {
122            return checkVal;
123        }
124    }
125
126    static class BogusException extends Throwable {
127
128        private static final long serialVersionUID = 1L;
129
130        public BogusException(String s) {
131            super(s);
132        }
133    }
134
135    // TODO android-added
136    class MonitoredClass {
137        public synchronized void enterLocked() {
138            boolean b = Thread.holdsLock(this);
139            assertTrue("Thread should hold lock for object", b);
140        }
141
142        public void enterNonLocked() {
143            boolean b = Thread.holdsLock(this);
144            assertFalse("Thread should not hold lock for object", b);
145        }
146    }
147
148    Thread st, ct, spinner;
149
150    static boolean calledMySecurityManager = false;
151
152    boolean wasInterrupted = false;
153
154    /**
155     * @tests java.lang.Thread#Thread()
156     */
157    @TestTargetNew(
158        level = TestLevel.COMPLETE,
159        notes = "",
160        method = "Thread",
161        args = {}
162    )
163    public void test_Constructor() {
164        // Test for method java.lang.Thread()
165
166        Thread t;
167        SecurityManager m = new SecurityManager() {
168            @Override
169            public ThreadGroup getThreadGroup() {
170                calledMySecurityManager = true;
171                return Thread.currentThread().getThreadGroup();
172            }
173
174            @Override
175            public void checkPermission(Permission permission) {
176                if (permission.getName().equals("setSecurityManager")) {
177                    return;
178                }
179                super.checkPermission(permission);
180            }
181        };
182        try {
183            // To see if it checks Thread creation with our SecurityManager
184            System.setSecurityManager(m);
185            t = new Thread();
186        } finally {
187            // restore original, no side-effects
188            System.setSecurityManager(null);
189        }
190        assertTrue("Did not call SecurityManager.getThreadGroup ()",
191                calledMySecurityManager);
192        t.start();
193    }
194
195    /**
196     * @tests java.lang.Thread#Thread(java.lang.Runnable)
197     */
198    @TestTargetNew(
199        level = TestLevel.COMPLETE,
200        notes = "",
201        method = "Thread",
202        args = {java.lang.Runnable.class}
203    )
204    public void test_ConstructorLjava_lang_Runnable() {
205        // Test for method java.lang.Thread(java.lang.Runnable)
206        try {
207            ct = new Thread(new SimpleThread(10));
208            ct.start();
209        } catch (Exception e) {
210            fail("Failed to create subthread : " + e.getMessage());
211        }
212    }
213
214    /**
215     * @tests java.lang.Thread#Thread(java.lang.Runnable, java.lang.String)
216     */
217    @TestTargetNew(
218        level = TestLevel.COMPLETE,
219        notes = "",
220        method = "Thread",
221        args = {java.lang.Runnable.class, java.lang.String.class}
222    )
223    public void test_ConstructorLjava_lang_RunnableLjava_lang_String() {
224        // Test for method java.lang.Thread(java.lang.Runnable,
225        // java.lang.String)
226        Thread st1 = new Thread(new SimpleThread(1), "SimpleThread1");
227        assertEquals("Constructed thread with incorrect thread name", "SimpleThread1", st1
228                .getName());
229        st1.start();
230    }
231
232    /**
233     * @tests java.lang.Thread#Thread(java.lang.String)
234     */
235    @TestTargetNew(
236        level = TestLevel.COMPLETE,
237        notes = "",
238        method = "Thread",
239        args = {java.lang.String.class}
240    )
241    public void test_ConstructorLjava_lang_String() {
242        // Test for method java.lang.Thread(java.lang.String)
243        Thread t = new Thread("Testing");
244        assertEquals("Created tread with incorrect name",
245                "Testing", t.getName());
246        t.start();
247    }
248
249    /**
250     * @tests java.lang.Thread#Thread(java.lang.ThreadGroup, java.lang.Runnable)
251     */
252    @TestTargetNew(
253        level = TestLevel.COMPLETE,
254        notes = "",
255        method = "Thread",
256        args = {java.lang.ThreadGroup.class, java.lang.Runnable.class}
257    )
258    public void test_ConstructorLjava_lang_ThreadGroupLjava_lang_Runnable() {
259        // Test for method java.lang.Thread(java.lang.ThreadGroup,
260        // java.lang.Runnable)
261        ThreadGroup tg = new ThreadGroup("Test Group1");
262        st = new Thread(tg, new SimpleThread(1), "SimpleThread2");
263        assertTrue("Returned incorrect thread group", st.getThreadGroup() == tg);
264        st.start();
265        try {
266            st.join();
267        } catch (InterruptedException e) {
268        }
269        tg.destroy();
270    }
271
272    /**
273     * @tests java.lang.Thread#Thread(java.lang.ThreadGroup, java.lang.Runnable,
274     *        java.lang.String)lo
275     */
276    @TestTargetNew(
277        level = TestLevel.COMPLETE,
278        notes = "",
279        method = "Thread",
280        args = {java.lang.ThreadGroup.class, java.lang.Runnable.class, java.lang.String.class}
281    )
282    public void test_ConstructorLjava_lang_ThreadGroupLjava_lang_RunnableLjava_lang_String() {
283        // Test for method java.lang.Thread(java.lang.ThreadGroup,
284        // java.lang.Runnable, java.lang.String)
285        ThreadGroup tg = new ThreadGroup("Test Group2");
286        st = new Thread(tg, new SimpleThread(1), "SimpleThread3");
287        assertTrue("Constructed incorrect thread", (st.getThreadGroup() == tg)
288                && st.getName().equals("SimpleThread3"));
289        st.start();
290        try {
291            st.join();
292        } catch (InterruptedException e) {
293        }
294        tg.destroy();
295
296        Runnable r = new Runnable() {
297            public void run() {
298            }
299        };
300
301        ThreadGroup foo = null;
302        try {
303            new Thread(foo = new ThreadGroup("foo"), r, null);
304            // Should not get here
305            fail("Null cannot be accepted as Thread name");
306        } catch (NullPointerException npe) {
307            assertTrue("Null cannot be accepted as Thread name", true);
308            foo.destroy();
309        }
310    }
311
312    @TestTargetNew(
313        level = TestLevel.COMPLETE,
314        notes = "",
315        method = "Thread",
316        args = {java.lang.ThreadGroup.class, java.lang.Runnable.class, java.lang.String.class, long.class}
317    )
318    public void test_ConstructorLjava_lang_ThreadGroupLjava_lang_RunnableLjava_lang_StringL$L() {
319        ThreadGroup tg = new ThreadGroup("Test Group2");
320        st = new Thread(tg, new SimpleThread(1), "SimpleThread3", 1);
321        assertTrue("Constructed incorrect thread", (st.getThreadGroup() == tg)
322                && st.getName().equals("SimpleThread3"));
323        st.start();
324        try {
325            st.join();
326        } catch (InterruptedException e) {
327        }
328        tg.destroy();
329
330        Runnable r = new Runnable() {
331            public void run() {
332            }
333        };
334
335        try {
336            new Thread(tg, new SimpleThread(1), "SimpleThread3",
337                    Integer.MAX_VALUE);
338            fail("StackOverflowError/OutOfMemoryError is not thrown.");
339        } catch(IllegalThreadStateException itse) {
340            //expected
341        }
342
343    }
344
345    /**
346     * @tests java.lang.Thread#Thread(java.lang.ThreadGroup, java.lang.String)
347     */
348    @TestTargetNew(
349        level = TestLevel.COMPLETE,
350        notes = "",
351        method = "Thread",
352        args = {java.lang.ThreadGroup.class, java.lang.String.class}
353    )
354    public void test_ConstructorLjava_lang_ThreadGroupLjava_lang_String() {
355        // Test for method java.lang.Thread(java.lang.ThreadGroup,
356        // java.lang.String)
357        st = new Thread(new SimpleThread(1), "SimpleThread4");
358        assertEquals("Returned incorrect thread name",
359                "SimpleThread4", st.getName());
360        st.start();
361    }
362
363    /**
364     * @tests java.lang.Thread#activeCount()
365     */
366    @TestTargetNew(
367        level = TestLevel.COMPLETE,
368        notes = "",
369        method = "activeCount",
370        args = {}
371    )
372    public void test_activeCount() {
373        // Test for method int java.lang.Thread.activeCount()
374        Thread t = new Thread(new SimpleThread(1));
375        int active = Thread.activeCount();
376        assertTrue("Incorrect read made: " + active, active > 0);
377        t.start();
378        try {
379            t.join();
380        } catch (InterruptedException e) {
381        }
382    }
383
384    /**
385     * @tests java.lang.Thread#checkAccess()
386     */
387    @TestTargetNew(
388        level = TestLevel.COMPLETE,
389        notes = "",
390        method = "checkAccess",
391        args = {}
392    )
393    public void test_checkAccess() {
394        // Test for method void java.lang.Thread.checkAccess()
395        ThreadGroup tg = new ThreadGroup("Test Group3");
396        try {
397            st = new Thread(tg, new SimpleThread(1), "SimpleThread5");
398            st.checkAccess();
399            assertTrue("CheckAccess passed", true);
400        } catch (SecurityException e) {
401            fail("CheckAccess failed : " + e.getMessage());
402        }
403        st.start();
404        try {
405            st.join();
406        } catch (InterruptedException e) {
407        }
408        tg.destroy();
409
410        SecurityManager sm = new SecurityManager() {
411
412            public void checkPermission(Permission perm) {
413            }
414
415            public void checkAccess(Thread t) {
416               throw new SecurityException();
417            }
418        };
419
420        SecurityManager oldSm = System.getSecurityManager();
421        System.setSecurityManager(sm);
422        try {
423            st.checkAccess();
424            fail("Should throw SecurityException");
425        } catch (SecurityException e) {
426            // expected
427        } finally {
428           System.setSecurityManager(oldSm);
429        }
430    }
431
432    /**
433     * @tests java.lang.Thread#countStackFrames()
434     */
435    @TestTargetNew(
436        level = TestLevel.COMPLETE,
437        notes = "",
438        method = "countStackFrames",
439        args = {}
440    )
441    @SuppressWarnings("deprecation")
442    public void test_countStackFrames() {
443        /*
444         * Thread.countStackFrames() is unpredictable, so we just test that it
445         * doesn't throw an exception.
446         */
447        try {
448            Thread.currentThread().countStackFrames();
449        } catch (Throwable t) {
450            fail("unexpected throwable: " + t.toString());
451        }
452    }
453
454    /**
455     * @tests java.lang.Thread#currentThread()
456     */
457    @TestTargetNew(
458        level = TestLevel.COMPLETE,
459        notes = "",
460        method = "currentThread",
461        args = {}
462    )
463    public void test_currentThread() {
464        assertNotNull(Thread.currentThread());
465    }
466
467    /**
468     * @tests java.lang.Thread#destroy()
469     */
470    @TestTargetNew(
471        level = TestLevel.COMPLETE,
472        notes = "",
473        method = "destroy",
474        args = {}
475    )
476    @SuppressWarnings("deprecation")
477    public void test_destroy() {
478        try {
479            new Thread().destroy();
480            // FIXME uncomment when IBM VME is updated
481            fail("NoSuchMethodError was not thrown");
482        } catch (NoSuchMethodError e) {
483        }
484    }
485
486    @TestTargetNew(
487        level = TestLevel.COMPLETE,
488        notes = "",
489        method = "dumpStack",
490        args = {}
491    )
492    public void test_dumpStack() {
493        try {
494            PrintStream savedErr = System.err;
495            ByteArrayOutputStream baos = new ByteArrayOutputStream();
496            System.setErr(new PrintStream(baos));
497            Thread.dumpStack();
498            System.setErr(savedErr);
499
500            String s = new String(baos.toByteArray());
501
502            assertTrue(s.contains("java.lang.Thread.dumpStack"));
503
504        } catch(Exception e) {
505            fail("Unexpected exception was thrown: " + e.toString());
506        }
507    }
508
509    /**
510     * @tests java.lang.Thread#enumerate(java.lang.Thread[])
511     */
512    @TestTargetNew(
513        level = TestLevel.COMPLETE,
514        notes = "",
515        method = "enumerate",
516        args = {java.lang.Thread[].class}
517    )
518    public void test_enumerate$Ljava_lang_Thread() {
519        // Test for method int java.lang.Thread.enumerate(java.lang.Thread [])
520        // The test has been updated according to HARMONY-1974 JIRA issue.
521
522        class MyThread extends Thread {
523            MyThread(ThreadGroup tg, String name) {
524                super(tg, name);
525            }
526
527            boolean failed = false;
528            String failMessage = null;
529
530            public void run() {
531                SimpleThread st1 = null;
532                SimpleThread st2 = null;
533                ThreadGroup mytg = null;
534                Thread firstOne = null;
535                Thread secondOne = null;
536                try {
537                    int arrayLength = 10;
538                    Thread[] tarray = new Thread[arrayLength];
539                    st1 = new SimpleThread(-1);
540                    st2 = new SimpleThread(-1);
541                    mytg = new ThreadGroup("jp");
542                    firstOne = new Thread(mytg, st1, "firstOne2");
543                    secondOne = new Thread(mytg, st2, "secondOne1");
544                    int orgCount = Thread.enumerate(tarray);
545                    synchronized (st1) {
546                        firstOne.start();
547                        try {
548                            st1.wait();
549                        } catch (InterruptedException e) {
550                        }
551                    }
552                    int count = Thread.enumerate(tarray);
553                    assertEquals("Incorrect value returned2",
554                            orgCount + 1, count);
555                    synchronized (st2) {
556                        secondOne.start();
557                        try {
558                            st2.wait();
559                        } catch (InterruptedException e) {
560                        }
561                    }
562                    count = Thread.enumerate(tarray);
563                    assertEquals("Incorrect value returned3",
564                            orgCount + 2, count);
565                } catch (junit.framework.AssertionFailedError e) {
566                    failed = true;
567                    failMessage = e.getMessage();
568                    e.printStackTrace();
569                } finally {
570                    synchronized (st1) {
571                        firstOne.interrupt();
572                    }
573                    synchronized (st2) {
574                        secondOne.interrupt();
575                    }
576                    try {
577                        firstOne.join();
578                        secondOne.join();
579                    } catch (InterruptedException e) {
580                    }
581                    mytg.destroy();
582                }
583            }
584        };
585
586        ThreadGroup tg = new ThreadGroup("tg");
587        MyThread t = new MyThread(tg, "top");
588        t.start();
589        try {
590            t.join();
591        } catch (InterruptedException e) {
592            fail("Unexpected interrupt");
593        } finally {
594            tg.destroy();
595        }
596        assertFalse(t.failMessage, t.failed);
597    }
598
599    /**
600     * @tests java.lang.Thread#getContextClassLoader()
601     */
602    @TestTargetNew(
603        level = TestLevel.COMPLETE,
604        notes = "",
605        method = "getContextClassLoader",
606        args = {}
607    )
608    public void test_getContextClassLoader() {
609        // Test for method java.lang.ClassLoader
610        // java.lang.Thread.getContextClassLoader()
611        Thread t = new Thread();
612        assertNotNull(Thread.currentThread().getContextClassLoader());
613        assertTrue("Incorrect class loader returned",
614                t.getContextClassLoader() == Thread.currentThread()
615                        .getContextClassLoader());
616    }
617
618    /**
619     * @tests java.lang.Thread#getName()
620     */
621    @TestTargetNew(
622        level = TestLevel.COMPLETE,
623        notes = "",
624        method = "getName",
625        args = {}
626    )
627    public void test_getName() {
628        // Test for method java.lang.String java.lang.Thread.getName()
629        st = new Thread(new SimpleThread(1), "SimpleThread6");
630        assertEquals("Returned incorrect thread name",
631                "SimpleThread6", st.getName());
632        st.start();
633    }
634
635    /**
636     * @tests java.lang.Thread#getPriority()
637     */
638    @TestTargetNew(
639        level = TestLevel.COMPLETE,
640        notes = "",
641        method = "getPriority",
642        args = {}
643    )
644    public void test_getPriority() {
645        // Test for method int java.lang.Thread.getPriority()
646        st = new Thread(new SimpleThread(1));
647        st.setPriority(Thread.MAX_PRIORITY);
648        assertTrue("Returned incorrect thread priority",
649                st.getPriority() == Thread.MAX_PRIORITY);
650        st.start();
651    }
652
653    /**
654     * @tests java.lang.Thread#getThreadGroup()
655     */
656    @TestTargetNew(
657        level = TestLevel.COMPLETE,
658        notes = "",
659        method = "getThreadGroup",
660        args = {}
661    )
662    public void test_getThreadGroup() {
663        // Test for method java.lang.ThreadGroup
664        // java.lang.Thread.getThreadGroup()
665        ThreadGroup tg = new ThreadGroup("Test Group4");
666        st = new Thread(tg, /* new SimpleThread(1), */ "SimpleThread8");
667        assertTrue("Returned incorrect thread group", st.getThreadGroup() == tg);
668        st.start();
669        try {
670            st.join();
671        } catch (InterruptedException e) {
672        }
673        assertNull("group should be null", st.getThreadGroup());
674        assertNotNull("toString() should not be null", st.toString());
675        tg.destroy();
676
677        final Object lock = new Object();
678        Thread t = new Thread() {
679            @Override
680            public void run() {
681                synchronized (lock) {
682                    lock.notifyAll();
683                }
684            }
685        };
686        synchronized (lock) {
687            t.start();
688            try {
689                lock.wait();
690            } catch (InterruptedException e) {
691            }
692        }
693        int running = 0;
694        while (t.isAlive())
695            running++;
696        ThreadGroup group = t.getThreadGroup();
697        assertNull("ThreadGroup is not null", group);
698    }
699
700    /**
701     * @tests java.lang.Thread#interrupt()
702     */
703    @TestTargetNew(
704        level = TestLevel.COMPLETE,
705        notes = "",
706        method = "interrupt",
707        args = {}
708    )
709    public void test_interrupt() {
710        // Test for method void java.lang.Thread.interrupt()
711        final Object lock = new Object();
712        class ChildThread1 extends Thread {
713            Thread parent;
714
715            boolean sync;
716
717            @Override
718            public void run() {
719                if (sync) {
720                    synchronized (lock) {
721                        lock.notify();
722                        try {
723                            lock.wait();
724                        } catch (InterruptedException e) {
725                        }
726                    }
727                }
728                parent.interrupt();
729            }
730
731            public ChildThread1(Thread p, String name, boolean sync) {
732                super(name);
733                parent = p;
734                this.sync = sync;
735            }
736        }
737        boolean interrupted = false;
738        try {
739            ct = new ChildThread1(Thread.currentThread(), "Interrupt Test1",
740                    false);
741            synchronized (lock) {
742                ct.start();
743                lock.wait();
744            }
745        } catch (InterruptedException e) {
746            interrupted = true;
747        }
748        assertTrue("Failed to Interrupt thread1", interrupted);
749
750        interrupted = false;
751        try {
752            ct = new ChildThread1(Thread.currentThread(), "Interrupt Test2",
753                    true);
754            synchronized (lock) {
755                ct.start();
756                lock.wait();
757                lock.notify();
758            }
759            Thread.sleep(20000);
760        } catch (InterruptedException e) {
761            interrupted = true;
762        }
763        assertTrue("Failed to Interrupt thread2", interrupted);
764
765        SecurityManager sm = new SecurityManager() {
766
767            public void checkPermission(Permission perm) {
768            }
769
770            public void checkAccess(Thread t) {
771               throw new SecurityException();
772            }
773        };
774        st = new Thread();
775        SecurityManager oldSm = System.getSecurityManager();
776        System.setSecurityManager(sm);
777        try {
778            st.interrupt();
779            fail("Should throw SecurityException");
780        } catch (SecurityException e) {
781            // expected
782        } finally {
783           System.setSecurityManager(oldSm);
784        }
785    }
786
787    /**
788     * @tests java.lang.Thread#interrupted()
789     */
790    @TestTargetNew(
791        level = TestLevel.COMPLETE,
792        notes = "",
793        method = "interrupted",
794        args = {}
795    )
796    public void test_interrupted() {
797        assertFalse("Interrupted returned true for non-interrupted thread", Thread
798                .interrupted());
799        Thread.currentThread().interrupt();
800        assertTrue("Interrupted returned true for non-interrupted thread", Thread.interrupted());
801        assertFalse("Failed to clear interrupted flag", Thread.interrupted());
802    }
803
804    /**
805     * @tests java.lang.Thread#isAlive()
806     */
807    @TestTargetNew(
808        level = TestLevel.COMPLETE,
809        notes = "",
810        method = "isAlive",
811        args = {}
812    )
813    public void test_isAlive() {
814        // Test for method boolean java.lang.Thread.isAlive()
815        SimpleThread simple;
816        st = new Thread(simple = new SimpleThread(500));
817        assertFalse("A thread that wasn't started is alive.", st.isAlive());
818        synchronized (simple) {
819            st.start();
820            try {
821                simple.wait();
822            } catch (InterruptedException e) {
823            }
824        }
825        assertTrue("Started thread returned false", st.isAlive());
826
827        try {
828            st.join();
829        } catch (InterruptedException e) {
830            fail("Thread did not die");
831        }
832        assertTrue("Stopped thread returned true", !st.isAlive());
833    }
834
835    /**
836     * @tests java.lang.Thread#isDaemon()
837     */
838    @TestTargetNew(
839        level = TestLevel.COMPLETE,
840        notes = "",
841        method = "isDaemon",
842        args = {}
843    )
844    public void test_isDaemon() {
845        // Test for method boolean java.lang.Thread.isDaemon()
846        st = new Thread(new SimpleThread(1), "SimpleThread10");
847        assertTrue("Non-Daemon thread returned true", !st.isDaemon());
848        st.setDaemon(true);
849        assertTrue("Daemon thread returned false", st.isDaemon());
850        st.start();
851    }
852
853    /**
854     * @tests java.lang.Thread#isInterrupted()
855     */
856    @TestTargetNew(
857        level = TestLevel.COMPLETE,
858        notes = "",
859        method = "isInterrupted",
860        args = {}
861    )
862    public void test_isInterrupted() {
863        // Test for method boolean java.lang.Thread.isInterrupted()
864        class SpinThread implements Runnable {
865            public volatile boolean done = false;
866
867            public void run() {
868                while (!Thread.currentThread().isInterrupted())
869                    ;
870                while (!done)
871                    ;
872            }
873        }
874
875        SpinThread spin = new SpinThread();
876        spinner = new Thread(spin);
877        spinner.start();
878        Thread.yield();
879        try {
880            assertTrue("Non-Interrupted thread returned true", !spinner
881                    .isInterrupted());
882            spinner.interrupt();
883            assertTrue("Interrupted thread returned false", spinner
884                    .isInterrupted());
885            spin.done = true;
886        } finally {
887            spinner.interrupt();
888            spin.done = true;
889        }
890    }
891
892    /**
893     * @tests java.lang.Thread#join()
894     */
895    @TestTargetNew(
896        level = TestLevel.COMPLETE,
897        notes = "",
898        method = "join",
899        args = {}
900    )
901    public void test_join() {
902        // Test for method void java.lang.Thread.join()
903        SimpleThread simple;
904        try {
905            st = new Thread(simple = new SimpleThread(100));
906            // cause isAlive() to be compiled by the JIT, as it must be called
907            // within 100ms below.
908            assertTrue("Thread is alive", !st.isAlive());
909            synchronized (simple) {
910                st.start();
911                simple.wait();
912            }
913            st.join();
914        } catch (InterruptedException e) {
915            fail("Join failed ");
916        }
917        assertFalse("Joined thread is still alive", st.isAlive());
918        boolean result = true;
919        Thread th = new Thread("test");
920        try {
921            th.join();
922        } catch (InterruptedException e) {
923            result = false;
924        }
925        assertTrue("Hung joining a non-started thread", result);
926        th.start();
927
928        st = new Thread() {
929            public void run() {
930                try {
931                    join();
932                    fail("InterruptedException was not thrown.");
933                } catch(InterruptedException ie) {
934                    //expected
935                }
936            }
937        };
938
939        st.start();
940    }
941
942    @TestTargetNew(
943            level = TestLevel.PARTIAL_COMPLETE,
944            notes = "Regression test for when join() failed due to spurious wakeups",
945            method = "join",
946            args = {long.class, int.class}
947    )
948    public void test_joinWithSpuriousInterruption() throws InterruptedException {
949        final Thread parker = new Thread() {
950            @Override
951            public void run() {
952                for (int i = 0; i < 10; i++) {
953                    // we used to get spurious wakeups upon unparking
954                    LockSupport.park();
955                }
956            }
957        };
958        Thread unparker = new Thread() {
959            @Override
960            public void run() {
961                for (int i = 0; i < 10; i++) {
962                    try {
963                        Thread.sleep(100);
964                        LockSupport.unpark(parker);
965                    } catch (InterruptedException ignored) {
966                    }
967                }
968            }
969        };
970
971        long startNanos = System.nanoTime();
972        parker.start();
973        unparker.start();
974        parker.join(500, 500000);
975        long netWaitTime = System.nanoTime() - startNanos;
976        assertTrue("Expected to wait at least 500000000ns, but was " + netWaitTime + "ns",
977                netWaitTime > 500000000);
978    }
979
980    /**
981     * @tests java.lang.Thread#join(long)
982     */
983    @TestTargetNew(
984        level = TestLevel.COMPLETE,
985        notes = "",
986        method = "join",
987        args = {long.class}
988    )
989    public void test_joinJ() {
990        // Test for method void java.lang.Thread.join(long)
991        SimpleThread simple;
992        try {
993            st = new Thread(simple = new SimpleThread(1000), "SimpleThread12");
994            // cause isAlive() to be compiled by the JIT, as it must be called
995            // within 100ms below.
996            assertTrue("Thread is alive", !st.isAlive());
997            synchronized (simple) {
998                st.start();
999                simple.wait();
1000            }
1001            st.join(10);
1002        } catch (InterruptedException e) {
1003            fail("Join failed ");
1004        }
1005        assertTrue("Join failed to timeout", st.isAlive());
1006
1007        st.interrupt();
1008        try {
1009            st = new Thread(simple = new SimpleThread(100), "SimpleThread13");
1010            synchronized (simple) {
1011                st.start();
1012                simple.wait();
1013            }
1014            st.join(1000);
1015        } catch (InterruptedException e) {
1016            fail("Join failed : " + e.getMessage());
1017            return;
1018        }
1019        assertTrue("Joined thread is still alive", !st.isAlive());
1020
1021        final Object lock = new Object();
1022        final Thread main = Thread.currentThread();
1023        Thread killer = new Thread(new Runnable() {
1024            public void run() {
1025                try {
1026                    synchronized (lock) {
1027                        lock.notify();
1028                    }
1029                    Thread.sleep(100);
1030                } catch (InterruptedException e) {
1031                    return;
1032                }
1033                main.interrupt();
1034            }
1035        });
1036        boolean result = true;
1037        Thread th = new Thread("test");
1038        try {
1039            synchronized (lock) {
1040                killer.start();
1041                lock.wait();
1042            }
1043            th.join(200);
1044        } catch (InterruptedException e) {
1045            result = false;
1046        }
1047        killer.interrupt();
1048        assertTrue("Hung joining a non-started thread", result);
1049        th.start();
1050
1051        st = new Thread() {
1052            public void run() {
1053                try {
1054                    join(1000);
1055                    fail("InterruptedException was not thrown.");
1056                } catch(InterruptedException ie) {
1057                    //expected
1058                }
1059            }
1060        };
1061
1062        st.start();
1063    }
1064
1065    /**
1066     * @tests java.lang.Thread#join(long, int)
1067     */
1068    @TestTargetNew(
1069        level = TestLevel.COMPLETE,
1070        notes = "",
1071        method = "join",
1072        args = {long.class, int.class}
1073    )
1074    public void test_joinJI() {
1075        // Test for method void java.lang.Thread.join(long, int)
1076        SimpleThread simple;
1077        try {
1078            st = new Thread(simple = new SimpleThread(1000), "Squawk1");
1079            assertTrue("Thread is alive", !st.isAlive());
1080            synchronized (simple) {
1081                st.start();
1082                simple.wait();
1083            }
1084
1085            long firstRead = System.currentTimeMillis();
1086            st.join(100, 999999);
1087            long secondRead = System.currentTimeMillis();
1088            assertTrue("Did not join by appropriate time: " + secondRead + "-"
1089                    + firstRead + "=" + (secondRead - firstRead), secondRead
1090                    - firstRead <= 300);
1091            assertTrue("Joined thread is not alive", st.isAlive());
1092            st.interrupt();
1093        } catch (Exception e) {
1094            fail("Exception during test : " + e.getMessage());
1095        }
1096
1097        final Object lock = new Object();
1098        final Thread main = Thread.currentThread();
1099        Thread killer = new Thread(new Runnable() {
1100            public void run() {
1101                try {
1102                    synchronized (lock) {
1103                        lock.notify();
1104                    }
1105                    Thread.sleep(100);
1106                } catch (InterruptedException e) {
1107                    return;
1108                }
1109                main.interrupt();
1110            }
1111        });
1112        boolean result = true;
1113        Thread th = new Thread("test");
1114        try {
1115            synchronized (lock) {
1116                killer.start();
1117                lock.wait();
1118            }
1119            th.join(200, 20);
1120        } catch (InterruptedException e) {
1121            result = false;
1122        }
1123        killer.interrupt();
1124        assertTrue("Hung joining a non-started thread", result);
1125        th.start();
1126
1127        st = new Thread() {
1128            public void run() {
1129                try {
1130                    join(1000, 20);
1131                    fail("InterruptedException was not thrown.");
1132                } catch(InterruptedException ie) {
1133                    //expected
1134                }
1135            }
1136        };
1137
1138        st.start();
1139    }
1140
1141    @TestTargets({
1142        @TestTargetNew(
1143            level = TestLevel.COMPLETE,
1144            notes = "",
1145            method = "setContextClassLoader",
1146            args = {java.lang.ClassLoader.class}
1147        ),
1148        @TestTargetNew(
1149            level = TestLevel.COMPLETE,
1150            notes = "",
1151            method = "getContextClassLoader",
1152            args = {}
1153        )
1154    })
1155    public void test_setContextClassLoader() {
1156        PublicClassLoader pcl = new PublicClassLoader();
1157        st = new Thread();
1158        st.setContextClassLoader(pcl);
1159        assertEquals(pcl, st.getContextClassLoader());
1160
1161        st.setContextClassLoader(null);
1162        assertNull(st.getContextClassLoader());
1163
1164        SecurityManager sm = new SecurityManager() {
1165            public void checkPermission(Permission perm) {
1166                if (perm.getName().equals("setContextClassLoader")
1167                        || perm.getName().equals("getClassLoader") ) {
1168                    throw new SecurityException();
1169                }
1170            }
1171        };
1172
1173        SecurityManager oldSm = System.getSecurityManager();
1174        System.setSecurityManager(sm);
1175        try {
1176            st.setContextClassLoader(pcl);
1177            fail("Should throw SecurityException");
1178        } catch (SecurityException e) {
1179            // expected
1180        } finally {
1181            System.setSecurityManager(oldSm);
1182        }
1183    }
1184
1185    private Thread launchFiveSecondDummyThread() {
1186        Thread thread = new Thread() {
1187            public void run() {
1188                try {
1189                    Thread.sleep(5000);
1190                } catch (InterruptedException e) {
1191                    // Ignore
1192                }
1193            }
1194        };
1195
1196        thread.start();
1197
1198        return thread;
1199    }
1200
1201    private class ThreadSecurityManager extends SecurityManager {
1202        public void checkPermission(Permission perm) {
1203        }
1204
1205        public void checkAccess(Thread t) {
1206            throw new SecurityException();
1207        }
1208    };
1209
1210    /**
1211     * @tests java.lang.Thread#resume()
1212     */
1213    @TestTargetNew(
1214        level = TestLevel.COMPLETE,
1215        notes = "",
1216        method = "resume",
1217        args = {}
1218    )
1219    @AndroidOnly("RI does implement this method, whereas Android does not")
1220    @SuppressWarnings("deprecation")
1221    public void test_resume() {
1222        Thread thread = launchFiveSecondDummyThread();
1223
1224        try {
1225            Thread.sleep(1000);
1226        } catch (InterruptedException e) {
1227            // Ignore
1228        }
1229
1230        // No-op in Android. Must neither have an effect nor throw an exception.
1231        Thread.State state = thread.getState();
1232        thread.resume();
1233        assertEquals(state, thread.getState());
1234
1235        // Security checks are made even though method is not supported.
1236        SecurityManager oldSm = System.getSecurityManager();
1237        System.setSecurityManager(new ThreadSecurityManager());
1238        try {
1239            thread.resume();
1240            fail("Should throw SecurityException");
1241        } catch (SecurityException e) {
1242            // expected
1243        } finally {
1244            System.setSecurityManager(oldSm);
1245        }
1246
1247        try {
1248            thread.join();
1249        } catch (InterruptedException e) {
1250            // Ignore
1251        }
1252    }
1253
1254    /**
1255     * @tests java.lang.Thread#run()
1256     */
1257    @TestTargetNew(
1258        level = TestLevel.COMPLETE,
1259        notes = "",
1260        method = "run",
1261        args = {}
1262    )
1263    public void test_run() {
1264        // Test for method void java.lang.Thread.run()
1265        class RunThread implements Runnable {
1266            boolean didThreadRun = false;
1267
1268            public void run() {
1269                didThreadRun = true;
1270            }
1271        }
1272        RunThread rt = new RunThread();
1273        Thread t = new Thread(rt);
1274        try {
1275            t.start();
1276            int count = 0;
1277            while (!rt.didThreadRun && count < 20) {
1278                Thread.sleep(100);
1279                count++;
1280            }
1281            assertTrue("Thread did not run", rt.didThreadRun);
1282            t.join();
1283        } catch (InterruptedException e) {
1284            assertTrue("Joined thread was interrupted", true);
1285        }
1286        assertTrue("Joined thread is still alive", !t.isAlive());
1287    }
1288
1289    /**
1290     * @tests java.lang.Thread#setDaemon(boolean)
1291     */
1292    @TestTargetNew(
1293        level = TestLevel.COMPLETE,
1294        notes = "",
1295        method = "setDaemon",
1296        args = {boolean.class}
1297    )
1298    public void test_setDaemonZ() {
1299        // Test for method void java.lang.Thread.setDaemon(boolean)
1300        st = new Thread(new SimpleThread(1), "SimpleThread14");
1301        st.setDaemon(true);
1302        assertTrue("Failed to set thread as daemon thread", st.isDaemon());
1303        st.start();
1304
1305        // BEGIN android-added
1306        st = new Thread(new SimpleThread(5));
1307        st.start();
1308        try {
1309            st.setDaemon(false);
1310            fail("setDaemon() must throw exception for started thread");
1311        } catch (IllegalThreadStateException ex) {
1312            // We expect this one.
1313        }
1314        // END android-added
1315
1316        SecurityManager sm = new SecurityManager() {
1317
1318            public void checkPermission(Permission perm) {
1319            }
1320
1321            public void checkAccess(Thread t) {
1322               throw new SecurityException();
1323            }
1324        };
1325
1326        SecurityManager oldSm = System.getSecurityManager();
1327        System.setSecurityManager(sm);
1328        try {
1329            st.setDaemon(false);
1330            fail("Should throw SecurityException");
1331        } catch (SecurityException e) {
1332            // expected
1333        } finally {
1334            System.setSecurityManager(oldSm);
1335        }
1336    }
1337
1338    /**
1339     * @tests java.lang.Thread#setName(java.lang.String)
1340     */
1341    @TestTargetNew(
1342        level = TestLevel.COMPLETE,
1343        notes = "",
1344        method = "setName",
1345        args = {java.lang.String.class}
1346    )
1347    public void test_setNameLjava_lang_String() {
1348        // Test for method void java.lang.Thread.setName(java.lang.String)
1349        st = new Thread(new SimpleThread(1), "SimpleThread15");
1350        st.setName("Bogus Name");
1351        assertEquals("Failed to set thread name",
1352                "Bogus Name", st.getName());
1353        try {
1354            st.setName(null);
1355            fail("Null should not be accepted as a valid name");
1356        } catch (NullPointerException e) {
1357            // success
1358            assertTrue("Null should not be accepted as a valid name", true);
1359        }
1360        st.start();
1361
1362        SecurityManager sm = new SecurityManager() {
1363
1364            public void checkPermission(Permission perm) {
1365            }
1366
1367            public void checkAccess(Thread t) {
1368               throw new SecurityException();
1369            }
1370        };
1371
1372        SecurityManager oldSm = System.getSecurityManager();
1373        System.setSecurityManager(sm);
1374        try {
1375            st.setName("Bogus Name");
1376            fail("Should throw SecurityException");
1377        } catch (SecurityException e) {
1378            // expected
1379        } finally {
1380           System.setSecurityManager(oldSm);
1381        }
1382    }
1383
1384    /**
1385     * @tests java.lang.Thread#setPriority(int)
1386     */
1387    @TestTargetNew(
1388        level = TestLevel.COMPLETE,
1389        notes = "",
1390        method = "setPriority",
1391        args = {int.class}
1392    )
1393    public void test_setPriorityI() {
1394        // Test for method void java.lang.Thread.setPriority(int)
1395        st = new Thread(new SimpleThread(1));
1396        st.setPriority(Thread.MAX_PRIORITY);
1397        assertTrue("Failed to set priority",
1398                st.getPriority() == Thread.MAX_PRIORITY);
1399        st.start();
1400
1401        SecurityManager sm = new SecurityManager() {
1402
1403            public void checkPermission(Permission perm) {
1404            }
1405
1406            public void checkAccess(Thread t) {
1407               throw new SecurityException();
1408            }
1409        };
1410
1411        SecurityManager oldSm = System.getSecurityManager();
1412        System.setSecurityManager(sm);
1413        try {
1414            st.setPriority(Thread.MIN_PRIORITY);
1415            fail("Should throw SecurityException");
1416        } catch (SecurityException e) {
1417            // expected
1418        } finally {
1419            System.setSecurityManager(oldSm);
1420        }
1421
1422        try {
1423            st.setPriority(Thread.MIN_PRIORITY - 1);
1424            fail("IllegalArgumentException is not thrown.");
1425        } catch(IllegalArgumentException iae) {
1426            //expected
1427        }
1428
1429        try {
1430            st.setPriority(Thread.MAX_PRIORITY + 1);
1431            fail("IllegalArgumentException is not thrown.");
1432        } catch(IllegalArgumentException iae) {
1433            //expected
1434        }
1435    }
1436
1437    /**
1438     * @tests java.lang.Thread#sleep(long)
1439     */
1440    @TestTargetNew(
1441        level = TestLevel.COMPLETE,
1442        notes = "",
1443        method = "sleep",
1444        args = {long.class}
1445    )
1446    public void test_sleepJ() {
1447        // Note: Not too much we can test here that can be reliably measured.
1448
1449        // Check that basic behavior is about right (with some tolerance)
1450        long stime = System.currentTimeMillis();
1451
1452        try {
1453            Thread.sleep(1000);
1454        } catch (InterruptedException e) {
1455            fail("Unexpected InterruptedException was thrown");
1456        }
1457
1458        long ftime = System.currentTimeMillis();
1459
1460        assertTrue("Failed to sleep long enough", (ftime - stime) >= 500);
1461        assertTrue("Failed to wake up early enough", (ftime - stime) <= 1500);
1462
1463        // Check that interrupt works
1464        st = new Thread() {
1465            public void run() {
1466                try {
1467                    sleep(10000);
1468                } catch(InterruptedException ie) {
1469                    wasInterrupted = true;
1470                }
1471            }
1472        };
1473
1474        st.start();
1475
1476        try {
1477            Thread.sleep(5000);
1478        } catch(InterruptedException e) {
1479            fail("Unexpected InterruptedException was thrown");
1480        }
1481
1482        st.interrupt();
1483
1484        try {
1485            Thread.sleep(5000);
1486        } catch(InterruptedException e) {
1487            fail("Unexpected InterruptedException was thrown");
1488        }
1489
1490        assertTrue(wasInterrupted);
1491    }
1492
1493    /**
1494     * @tests java.lang.Thread#sleep(long, int)
1495     */
1496    @TestTargetNew(
1497        level = TestLevel.COMPLETE,
1498        notes = "",
1499        method = "sleep",
1500        args = {long.class, int.class}
1501    )
1502    public void test_sleepJI() {
1503        // Note: Not too much we can test here that can be reliably measured.
1504
1505        // Check that basic behavior is about right (with some tolerance)
1506        long stime = System.currentTimeMillis();
1507
1508        try {
1509            Thread.sleep(1000, 99999);
1510        } catch (InterruptedException e) {
1511            fail("Unexpected InterruptedException was thrown");
1512        }
1513
1514        long ftime = System.currentTimeMillis();
1515
1516        assertTrue("Failed to sleep long enough", (ftime - stime) >= 500);
1517        assertTrue("Failed to wake up early enough", (ftime - stime) <= 1500);
1518
1519        // Check that interrupt works
1520        st = new Thread() {
1521            public void run() {
1522                try {
1523                    sleep(10000, 99999);
1524                } catch(InterruptedException ie) {
1525                    wasInterrupted = true;
1526                }
1527            }
1528        };
1529
1530        st.start();
1531
1532        try {
1533            Thread.sleep(5000, 99999);
1534        } catch(InterruptedException e) {
1535            fail("Unexpected InterruptedException was thrown");
1536        }
1537
1538        st.interrupt();
1539
1540        try {
1541            Thread.sleep(5000);
1542        } catch(InterruptedException e) {
1543            fail("Unexpected InterruptedException was thrown");
1544        }
1545
1546        assertTrue(wasInterrupted);
1547    }
1548
1549    /**
1550     * @tests java.lang.Thread#start()
1551     */
1552    @TestTargetNew(
1553        level = TestLevel.COMPLETE,
1554        notes = "",
1555        method = "start",
1556        args = {}
1557    )
1558    public void test_start() {
1559        // Test for method void java.lang.Thread.start()
1560        try {
1561            ResSupThread t = new ResSupThread(Thread.currentThread());
1562            synchronized (t) {
1563                ct = new Thread(t, "Interrupt Test4");
1564                ct.start();
1565                t.wait();
1566            }
1567            assertTrue("Thread is not running1", ct.isAlive());
1568            // Let the child thread get going.
1569            int orgval = t.getCheckVal();
1570            Thread.sleep(150);
1571            assertTrue("Thread is not running2", orgval != t.getCheckVal());
1572            ct.interrupt();
1573        } catch (InterruptedException e) {
1574            fail("Unexpected interrupt occurred");
1575        }
1576        Thread thr = new Thread();
1577        thr.start();
1578        try {
1579            thr.start();
1580        } catch(IllegalThreadStateException itse){
1581            //expected
1582        }
1583    }
1584
1585    /**
1586     * @tests java.lang.Thread#stop()
1587     */
1588    @TestTargetNew(
1589        level = TestLevel.COMPLETE,
1590        notes = "",
1591        method = "stop",
1592        args = {}
1593    )
1594    @AndroidOnly("RI does implement this method, whereas Android does not")
1595    @SuppressWarnings("deprecation")
1596    public void test_stop() {
1597        Thread thread = launchFiveSecondDummyThread();
1598
1599        try {
1600            Thread.sleep(1000);
1601        } catch (InterruptedException e) {
1602            // Ignore
1603        }
1604
1605        // No-op in Android. Must neither have an effect nor throw an exception.
1606        Thread.State state = thread.getState();
1607        thread.stop();
1608        assertEquals(state, thread.getState());
1609
1610        // Security checks are made even though method is not supported.
1611        SecurityManager oldSm = System.getSecurityManager();
1612        System.setSecurityManager(new ThreadSecurityManager());
1613        try {
1614            thread.stop();
1615            fail("Should throw SecurityException");
1616        } catch (SecurityException e) {
1617            // expected
1618        } finally {
1619            System.setSecurityManager(oldSm);
1620        }
1621
1622        try {
1623            thread.join();
1624        } catch (InterruptedException e) {
1625            // Ignore
1626        }
1627    }
1628
1629    /**
1630     * @tests java.lang.Thread#stop(java.lang.Throwable)
1631     */
1632    @TestTargetNew(
1633        level = TestLevel.COMPLETE,
1634        notes = "Verifies security.",
1635        method = "stop",
1636        args = {java.lang.Throwable.class}
1637    )
1638    @SuppressWarnings("deprecation")
1639    public void test_stopLjava_lang_Throwable_subtest0() {
1640        Thread thread = new Thread() {
1641            public void run() {
1642                try {
1643                    Thread.sleep(5000);
1644                } catch (InterruptedException e) {
1645                    // Ignore
1646                }
1647            }
1648        };
1649
1650        thread.start();
1651        try {
1652            Thread.sleep(1000);
1653        } catch (InterruptedException e) {
1654            // Ignore
1655        }
1656
1657        // No-op in Android. Must neither have an effect nor throw an exception.
1658        Thread.State state = thread.getState();
1659        thread.stop(new Exception("Oops!"));
1660        assertEquals(state, thread.getState());
1661
1662        // Security checks are made even though method is not supported.
1663        SecurityManager sm = new SecurityManager() {
1664            public void checkPermission(Permission perm) {
1665            }
1666
1667            public void checkAccess(Thread t) {
1668                throw new SecurityException();
1669            }
1670        };
1671
1672        SecurityManager oldSm = System.getSecurityManager();
1673        System.setSecurityManager(sm);
1674        try {
1675            thread.stop();
1676            fail("Should throw SecurityException");
1677        } catch (SecurityException e) {
1678            // expected
1679        } finally {
1680            System.setSecurityManager(oldSm);
1681        }
1682
1683        try {
1684            thread.join();
1685        } catch (InterruptedException e) {
1686            // Ignore
1687        }
1688    }
1689
1690    /**
1691     * @tests java.lang.Thread#suspend()
1692     */
1693    @TestTargetNew(
1694        level = TestLevel.COMPLETE,
1695        notes = "",
1696        method = "suspend",
1697        args = {}
1698    )
1699    @AndroidOnly("RI does implement this method, whereas Android does not")
1700    @SuppressWarnings("deprecation")
1701    public void test_suspend() {
1702        Thread thread = launchFiveSecondDummyThread();
1703
1704        try {
1705            Thread.sleep(1000);
1706        } catch (InterruptedException e) {
1707            // Ignore
1708        }
1709
1710        // No-op in Android. Must neither have an effect nor throw an exception.
1711        Thread.State state = thread.getState();
1712        thread.suspend();
1713        assertEquals(state, thread.getState());
1714
1715        // Security checks are made even though method is not supported.
1716        SecurityManager oldSm = System.getSecurityManager();
1717        System.setSecurityManager(new ThreadSecurityManager());
1718        try {
1719            thread.suspend();
1720            fail("Should throw SecurityException");
1721        } catch (SecurityException e) {
1722            // expected
1723        } finally {
1724            System.setSecurityManager(oldSm);
1725        }
1726
1727        try {
1728            thread.join();
1729        } catch (InterruptedException e) {
1730            // Ignore
1731        }
1732    }
1733
1734    /**
1735     * @tests java.lang.Thread#toString()
1736     */
1737    @TestTargetNew(
1738        level = TestLevel.COMPLETE,
1739        notes = "",
1740        method = "toString",
1741        args = {}
1742    )
1743    public void test_toString() {
1744        // Test for method java.lang.String java.lang.Thread.toString()
1745        ThreadGroup tg = new ThreadGroup("Test Group5");
1746        st = new Thread(tg, new SimpleThread(1), "SimpleThread17");
1747        final String stString = st.toString();
1748        final String expected = "Thread[SimpleThread17,5,Test Group5]";
1749        assertTrue("Returned incorrect string: " + stString + "\t(expecting :"
1750                + expected + ")", stString.equals(expected));
1751        st.start();
1752        try {
1753            st.join();
1754        } catch (InterruptedException e) {
1755        }
1756        tg.destroy();
1757    }
1758
1759    @TestTargetNew(
1760        level = TestLevel.COMPLETE,
1761        notes = "",
1762        method = "yield",
1763        args = {}
1764    )
1765    public void test_yield() {
1766
1767        Counter [] countersNotYeld = new Counter[10];
1768
1769        for(int i = 0; i < 10; i++) {
1770            countersNotYeld[i] = new Counter(false);
1771        }
1772        Counter countersYeld = new Counter(true);
1773        try {
1774            Thread.sleep(11000);
1775        } catch(InterruptedException ie) {}
1776
1777        for(Counter c:countersNotYeld) {
1778            assertTrue(countersYeld.counter == c.counter);
1779        }
1780    }
1781
1782    class Counter extends Thread {
1783        public int counter = 0;
1784        boolean isDoYield = false;
1785
1786        public Counter(boolean isDoYield) {
1787            this.isDoYield = isDoYield;
1788            start();
1789        }
1790
1791        public void run() {
1792            for(int i = 0; i < 10000; i++) {
1793                if(isDoYield)
1794                    yield();
1795                counter ++;
1796            }
1797        }
1798    }
1799
1800
1801    /**
1802     * @tests java.lang.Thread#getAllStackTraces()
1803     */
1804    @TestTargetNew(
1805        level = TestLevel.COMPLETE,
1806        notes = "",
1807        method = "getAllStackTraces",
1808        args = {}
1809    )
1810    public void test_getAllStackTraces() {
1811        Map<Thread, StackTraceElement[]> stMap = Thread.getAllStackTraces();
1812        assertNotNull(stMap);
1813        //TODO add security-based tests
1814
1815        SecurityManager sm = new SecurityManager() {
1816
1817            public void checkPermission(Permission perm) {
1818                if(perm.getName().equals("modifyThreadGroup")) {
1819                    throw new SecurityException();
1820                }
1821            }
1822        };
1823
1824        SecurityManager oldSm = System.getSecurityManager();
1825        System.setSecurityManager(sm);
1826        try {
1827            Thread.getAllStackTraces();
1828            fail("Should throw SecurityException");
1829        } catch (SecurityException e) {
1830            // expected
1831        } finally {
1832           System.setSecurityManager(oldSm);
1833        }
1834    }
1835
1836    /**
1837     * @tests java.lang.Thread#getDefaultUncaughtExceptionHandler
1838     * @tests java.lang.Thread#setDefaultUncaughtExceptionHandler
1839     */
1840    @TestTargets({
1841        @TestTargetNew(
1842            level = TestLevel.COMPLETE,
1843            notes = "",
1844            method = "setDefaultUncaughtExceptionHandler",
1845            args = {java.lang.Thread.UncaughtExceptionHandler.class}
1846        ),
1847        @TestTargetNew(
1848            level = TestLevel.COMPLETE,
1849            notes = "",
1850            method = "getDefaultUncaughtExceptionHandler",
1851            args = {}
1852        )
1853    })
1854    public void test_get_setDefaultUncaughtExceptionHandler() {
1855        class Handler implements UncaughtExceptionHandler {
1856            public void uncaughtException(Thread thread, Throwable ex) {
1857            }
1858        }
1859
1860        final Handler handler = new Handler();
1861        Thread.setDefaultUncaughtExceptionHandler(handler);
1862        assertSame(handler, Thread.getDefaultUncaughtExceptionHandler());
1863
1864        Thread.setDefaultUncaughtExceptionHandler(null);
1865        assertNull(Thread.getDefaultUncaughtExceptionHandler());
1866        //TODO add security-based tests
1867
1868        SecurityManager sm = new SecurityManager() {
1869
1870            public void checkPermission(Permission perm) {
1871                if(perm.getName().
1872                        equals("setDefaultUncaughtExceptionHandler")) {
1873                    throw new SecurityException();
1874                }
1875            }
1876        };
1877
1878        SecurityManager oldSm = System.getSecurityManager();
1879        System.setSecurityManager(sm);
1880        try {
1881            st.setDefaultUncaughtExceptionHandler(handler);
1882            fail("Should throw SecurityException");
1883        } catch (SecurityException e) {
1884            // expected
1885        }  finally {
1886            System.setSecurityManager(oldSm);
1887        }
1888    }
1889
1890    /**
1891     * @tests java.lang.Thread#getStackTrace()
1892     */
1893    @TestTargetNew(
1894        level = TestLevel.COMPLETE,
1895        notes = "",
1896        method = "getStackTrace",
1897        args = {}
1898    )
1899    public void test_getStackTrace() {
1900        StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
1901
1902        assertNotNull(stackTrace);
1903
1904        stack_trace_loop: {
1905            for (int i = 0; i < stackTrace.length; i++) {
1906                StackTraceElement e = stackTrace[i];
1907                if (getClass().getName().equals(e.getClassName())) {
1908                    if ("test_getStackTrace".equals(e.getMethodName())) {
1909                        break stack_trace_loop;
1910                    }
1911                }
1912            }
1913            fail("class and method not found in stack trace");
1914        }
1915
1916        //TODO add security-based tests
1917
1918        SecurityManager sm = new SecurityManager() {
1919
1920            public void checkPermission(Permission perm) {
1921                if(perm.getName().
1922                        equals("getStackTrace")) {
1923                    throw new SecurityException();
1924                }
1925            }
1926        };
1927        st = new Thread();
1928        SecurityManager oldSm = System.getSecurityManager();
1929        System.setSecurityManager(sm);
1930        try {
1931            st.getStackTrace();
1932            fail("Should throw SecurityException");
1933        } catch (SecurityException e) {
1934            // expected
1935        }  finally {
1936            System.setSecurityManager(oldSm);
1937        }
1938    }
1939
1940    /**
1941     * @tests java.lang.Thread#getState()
1942     */
1943    @TestTargetNew(
1944        level = TestLevel.COMPLETE,
1945        notes = "",
1946        method = "getState",
1947        args = {}
1948    )
1949    public void test_getState() {
1950        Thread.State state = Thread.currentThread().getState();
1951        assertNotNull(state);
1952        assertEquals(Thread.State.RUNNABLE, state);
1953
1954        final Semaphore sem = new Semaphore(0);
1955        final Object lock = new Object();
1956        Thread th = new Thread() {
1957            @Override
1958            public void run() {
1959                  while (!sem.hasQueuedThreads()) {}
1960                  sem.release();
1961
1962                  // RUNNABLE
1963                  while (run) {}
1964
1965                  try {
1966                      // WAITING
1967                      sem.acquire();
1968                  } catch (InterruptedException e) {
1969                      fail("InterruptedException was thrown.");
1970                  }
1971
1972                  // BLOCKED
1973                  synchronized (lock) {
1974                      lock.equals(new Object());
1975                  }
1976                  synchronized (lock) {
1977                      try {
1978                        sem.release();
1979
1980                        // TIMED_WAITING
1981                        lock.wait(Long.MAX_VALUE);
1982                      } catch (InterruptedException e) {
1983                          // expected
1984                      }
1985                  }
1986
1987                  // TERMINATED upon return
1988            }
1989        };
1990        assertEquals(Thread.State.NEW, th.getState());
1991        th.start();
1992        try {
1993            sem.acquire();
1994        } catch (InterruptedException e) {
1995            fail("InterruptedException was thrown.");
1996        }
1997        assertEquals(Thread.State.RUNNABLE, th.getState());
1998        run = false;
1999
2000        while (!sem.hasQueuedThreads()){}
2001
2002        assertEquals(Thread.State.WAITING, th.getState());
2003        synchronized (lock) {
2004            sem.release();
2005            long start = System.currentTimeMillis();
2006            while(start + 1000 > System.currentTimeMillis()) {}
2007            assertEquals(Thread.State.BLOCKED, th.getState());
2008        }
2009
2010        try {
2011            sem.acquire();
2012        } catch (InterruptedException e) {
2013            fail("InterruptedException was thrown.");
2014        }
2015
2016        synchronized (lock) {
2017            assertEquals(Thread.State.TIMED_WAITING, th.getState());
2018            th.interrupt();
2019        }
2020
2021        try {
2022            th.join(1000);
2023        } catch(InterruptedException ie) {
2024            fail("InterruptedException was thrown.");
2025        }
2026        assertEquals(Thread.State.TERMINATED, th.getState());
2027    }
2028    volatile boolean run = true;
2029
2030    /**
2031     * @tests java.lang.Thread#getUncaughtExceptionHandler
2032     * @tests java.lang.Thread#setUncaughtExceptionHandler
2033     */
2034    @TestTargets({
2035        @TestTargetNew(
2036            level = TestLevel.COMPLETE,
2037            notes = "",
2038            method = "getUncaughtExceptionHandler",
2039            args = {}
2040        ),
2041        @TestTargetNew(
2042            level = TestLevel.COMPLETE,
2043            notes = "",
2044            method = "setUncaughtExceptionHandler",
2045            args = {java.lang.Thread.UncaughtExceptionHandler.class}
2046        )
2047    })
2048    public void test_get_setUncaughtExceptionHandler() {
2049        class Handler implements UncaughtExceptionHandler {
2050            public void uncaughtException(Thread thread, Throwable ex) {
2051            }
2052        }
2053
2054        final Handler handler = new Handler();
2055        Thread.currentThread().setUncaughtExceptionHandler(handler);
2056        assertSame(handler, Thread.currentThread().getUncaughtExceptionHandler());
2057
2058        Thread.currentThread().setUncaughtExceptionHandler(null);
2059
2060        //TODO add security-based tests
2061        SecurityManager sm = new SecurityManager() {
2062
2063            public void checkPermission(Permission perm) {
2064            }
2065
2066            public void checkAccess(Thread t) {
2067               throw new SecurityException();
2068            }
2069        };
2070        st = new Thread();
2071        SecurityManager oldSm = System.getSecurityManager();
2072        System.setSecurityManager(sm);
2073        try {
2074            st.setUncaughtExceptionHandler(handler);
2075            fail("Should throw SecurityException");
2076        } catch (SecurityException e) {
2077            // expected
2078        } finally {
2079            System.setSecurityManager(oldSm);
2080        }
2081
2082    }
2083
2084    /**
2085     * @tests java.lang.Thread#getId()
2086     */
2087    @TestTargetNew(
2088        level = TestLevel.COMPLETE,
2089        notes = "",
2090        method = "getId",
2091        args = {}
2092    )
2093    public void test_getId() {
2094        assertTrue("current thread's ID is not positive", Thread.currentThread().getId() > 0);
2095
2096        //check all the current threads for positive IDs
2097        Map<Thread, StackTraceElement[]> stMap = Thread.getAllStackTraces();
2098        for (Thread thread : stMap.keySet()) {
2099            assertTrue("thread's ID is not positive: " + thread.getName(), thread.getId() > 0);
2100        }
2101    }
2102
2103    /**
2104     * @tests java.lang.Thread#holdLock()
2105     */
2106    @TestTargetNew(
2107        level = TestLevel.COMPLETE,
2108        notes = "",
2109        method = "holdsLock",
2110        args = {java.lang.Object.class}
2111    )
2112    public void test_holdsLock() {
2113        MonitoredClass monitor = new MonitoredClass();
2114
2115        monitor.enterLocked();
2116        monitor.enterNonLocked();
2117
2118        try {
2119            Thread.holdsLock(null);
2120            fail("NullPointerException was not thrown.");
2121        } catch(NullPointerException npe) {
2122            //expected
2123        }
2124    }
2125
2126    @Override
2127    protected void tearDown() {
2128        try {
2129            if (st != null)
2130                st.interrupt();
2131        } catch (Exception e) {
2132        }
2133        try {
2134            if (spinner != null)
2135                spinner.interrupt();
2136        } catch (Exception e) {
2137        }
2138        try {
2139            if (ct != null)
2140                ct.interrupt();
2141        } catch (Exception e) {
2142        }
2143
2144        try {
2145            spinner = null;
2146            st = null;
2147            ct = null;
2148            System.runFinalization();
2149        } catch (Exception e) {
2150        }
2151    }
2152}
2153