ObjectTest.java revision f6c387128427e121477c1b32ad35cdcaa5101ba3
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 */
17package org.apache.harmony.luni.tests.java.lang;
18
19import java.util.Vector;
20
21import dalvik.annotation.TestTargets;
22import dalvik.annotation.TestLevel;
23import dalvik.annotation.TestTargetNew;
24import dalvik.annotation.TestTargetClass;
25
26@TestTargetClass(Object.class)
27public class ObjectTest extends junit.framework.TestCase {
28
29    public boolean isCalled = false;
30    /**
31     * Test objects.
32     */
33    Object obj1 = new Object();
34
35    Object obj2 = new Object();
36
37    /**
38     * Generic state indicator.
39     */
40    int status = 0;
41
42    int ready = 0;
43    TestThread1 thr1;
44    TestThread2 thr2;
45
46    /**
47     * @tests java.lang.Object#Object()
48     */
49    @TestTargetNew(
50        level = TestLevel.COMPLETE,
51        notes = "",
52        method = "Object",
53        args = {}
54    )
55    public void test_Constructor() {
56        // Test for method java.lang.Object()
57        assertNotNull("Constructor failed !!!", new Object());
58    }
59
60    /**
61     * @tests java.lang.Object#equals(java.lang.Object)
62     */
63    @TestTargetNew(
64        level = TestLevel.COMPLETE,
65        notes = "",
66        method = "equals",
67        args = {java.lang.Object.class}
68    )
69    public void test_equalsLjava_lang_Object() {
70        // Test for method boolean java.lang.Object.equals(java.lang.Object)
71        assertTrue("Same object should be equal", obj1.equals(obj1));
72        assertTrue("Different objects should not be equal", !obj1.equals(obj2));
73    }
74
75    @TestTargetNew(
76        level = TestLevel.COMPLETE,
77        notes = "",
78        method = "finalize",
79        args = {}
80    )
81
82    public void test_finalize() {
83        isCalled = false;
84        class TestObject extends Object {
85
86            Vector<StringBuffer> v = new Vector<StringBuffer>();
87            public void add() {
88                v.add(new StringBuffer(10000));
89            }
90
91            protected void finalize() throws Throwable {
92                isCalled = true;
93                super.finalize();
94            }
95        }
96
97        TestObject to = new TestObject();
98
99        try {
100            while(true) {
101                to.add();
102            }
103        } catch(OutOfMemoryError oome) {
104            //expected
105            to = null;
106        }
107        System.gc();
108        System.runFinalization();
109        assertTrue(isCalled);
110    }
111
112    @TestTargetNew(
113        level = TestLevel.COMPLETE,
114        notes = "",
115        method = "clone",
116        args = {}
117    )
118    public void test_clone() {
119        MockCloneableObject mco = new MockCloneableObject();
120        try {
121            assertFalse(mco.equals(mco.clone()));
122            assertEquals(mco.getClass(), mco.clone().getClass());
123        } catch(CloneNotSupportedException cnse) {
124            fail("CloneNotSupportedException was thrown.");
125        }
126
127        MockObject mo = new MockObject();
128        try {
129            mo.clone();
130            fail("CloneNotSupportedException was not thrown.");
131        } catch(CloneNotSupportedException cnse) {
132            //expected
133        }
134    }
135    class MockCloneableObject extends Object implements Cloneable {
136        public Object clone() throws CloneNotSupportedException {
137            return super.clone();
138        }
139    }
140
141    class MockObject extends Object {
142
143        boolean isCalled = false;
144
145        public void finalize() throws Throwable {
146            super.finalize();
147            isCalled = true;
148        }
149
150        public Object clone() throws CloneNotSupportedException {
151            return super.clone();
152        }
153    }
154
155    /**
156     * @tests java.lang.Object#getClass()
157     */
158    @TestTargetNew(
159        level = TestLevel.COMPLETE,
160        notes = "",
161        method = "getClass",
162        args = {}
163    )
164    public void test_getClass() {
165        // Test for method java.lang.Class java.lang.Object.getClass()
166        String classNames[] = { "java.lang.Object", "java.lang.Throwable",
167                "java.lang.StringBuffer" };
168        Class<?> classToTest = null;
169        Object instanceToTest = null;
170
171        status = 0;
172        for (int i = 0; i < classNames.length; ++i) {
173            try {
174                classToTest = Class.forName(classNames[i]);
175                instanceToTest = classToTest.newInstance();
176                assertTrue("Instance didn't match creator class.",
177                        instanceToTest.getClass() == classToTest);
178                assertTrue("Instance didn't match class with matching name.",
179                        instanceToTest.getClass() == Class
180                                .forName(classNames[i]));
181            } catch (Exception ex) {
182                fail("Unexpected exception : " + ex.getMessage());
183            }
184        }
185    }
186
187    /**
188     * @tests java.lang.Object#hashCode()
189     */
190    @TestTargetNew(
191        level = TestLevel.COMPLETE,
192        notes = "",
193        method = "hashCode",
194        args = {}
195    )
196    public void test_hashCode() {
197        // Test for method int java.lang.Object.hashCode()
198        assertTrue("Same object should have same hash.",
199                obj1.hashCode() == obj1.hashCode());
200        assertTrue("Same object should have same hash.",
201                obj2.hashCode() == obj2.hashCode());
202    }
203
204    /**
205     * @tests java.lang.Object#notify()
206     */
207    @TestTargetNew(
208        level = TestLevel.COMPLETE,
209        notes = "",
210        method = "notify",
211        args = {}
212    )
213    public void test_notify() {
214        // Test for method void java.lang.Object.notify()
215
216        // Inner class to run test thread.
217        class TestThread implements Runnable {
218            public void run() {
219                synchronized (obj1) {
220                    try {
221                        ready += 1;
222                        obj1.wait();// Wait for ever.
223                        status += 1;
224                    } catch (InterruptedException ex) {
225                        status = -1000;
226                    }
227                }
228            }
229        }
230        ;
231
232        // Start of test code.
233
234        // Warning:
235        // This code relies on each thread getting serviced within
236        // 200 mSec of when it is notified. Although this
237        // seems reasonable, it could lead to false-failures.
238
239        ready = 0;
240        status = 0;
241        final int readyWaitSecs = 3;
242
243        final int threadCount = 20;
244        for (int i = 0; i < threadCount; ++i) {
245            new Thread(new TestThread()).start();
246        }
247        synchronized (obj1) {
248            try {
249
250                // Wait up to readyWaitSeconds for all threads to be waiting on
251                // monitor
252                for (int i = 0; i < readyWaitSecs; i++) {
253                    obj1.wait(1000, 0);
254                    if (ready == threadCount) {
255                        break;
256                    }
257                }
258
259                // Check pre-conditions of testing notifyAll
260                assertTrue("Not all launched threads are waiting. (ready = "
261                        + ready + ")", ready == threadCount);
262                assertTrue("Thread woke too early. (status = " + status + ")",
263                        status == 0);
264
265                for (int i = 1; i <= threadCount; ++i) {
266                    obj1.notify();
267                    obj1.wait(200, 0);
268                    assertTrue("Out of sync. (expected " + i + " but got "
269                            + status + ")", status == i);
270                }
271
272            } catch (InterruptedException ex) {
273                fail(
274                        "Unexpectedly got an InterruptedException. (status = "
275                                + status + ")");
276            }
277        }
278
279        try {
280            Object obj = new Object();
281            obj.notify();
282            fail("IllegalMonitorStateException was not thrown.");
283        } catch(IllegalMonitorStateException imse) {
284            //expected
285        }
286    }
287
288    /**
289     * @tests java.lang.Object#notifyAll()
290     */
291    @TestTargetNew(
292        level = TestLevel.COMPLETE,
293        notes = "",
294        method = "notifyAll",
295        args = {}
296    )
297    public void test_notifyAll() {
298        // Test for method void java.lang.Object.notifyAll()
299
300        // Inner class to run test thread.
301        class TestThread implements Runnable {
302            public void run() {
303                synchronized (obj1) {
304                    try {
305                        ready += 1;
306                        obj1.wait();// Wait for ever.
307                        status += 1;
308                    } catch (InterruptedException ex) {
309                        status = -1000;
310                    }
311                }
312            }
313        }
314        ;
315
316        // Start of test code.
317
318        // Warning:
319        // This code relies on all threads getting serviced within
320        // 5 seconds of when they are notified. Although this
321        // seems reasonable, it could lead to false-failures.
322
323        status = 0;
324        ready = 0;
325        final int readyWaitSecs = 3;
326        final int threadCount = 20;
327        for (int i = 0; i < threadCount; ++i) {
328            new Thread(new TestThread()).start();
329        }
330
331        synchronized (obj1) {
332
333            try {
334
335                // Wait up to readyWaitSeconds for all threads to be waiting on
336                // monitor
337                for (int i = 0; i < readyWaitSecs; i++) {
338                    obj1.wait(1000, 0);
339                    if (ready == threadCount) {
340                        break;
341                    }
342                }
343
344                // Check pre-conditions of testing notifyAll
345                assertTrue("Not all launched threads are waiting. (ready = "
346                        + ready + ")", ready == threadCount);
347                assertTrue("At least one thread woke too early. (status = "
348                        + status + ")", status == 0);
349
350                obj1.notifyAll();
351
352                obj1.wait(5000, 0);
353
354                assertTrue(
355                        "At least one thread did not get notified. (status = "
356                                + status + ")", status == threadCount);
357
358            } catch (InterruptedException ex) {
359                fail(
360                        "Unexpectedly got an InterruptedException. (status = "
361                                + status + ")");
362            }
363
364        }
365
366        try {
367            Object obj = new Object();
368            obj.notifyAll();
369            fail("IllegalMonitorStateException was not thrown.");
370        } catch(IllegalMonitorStateException imse) {
371            //expected
372        }
373    }
374
375    /**
376     * @tests java.lang.Object#toString()
377     */
378    @TestTargetNew(
379        level = TestLevel.COMPLETE,
380        notes = "",
381        method = "toString",
382        args = {}
383    )
384    public void test_toString() {
385        // Test for method java.lang.String java.lang.Object.toString()
386        assertNotNull("Object toString returned null.", obj1.toString());
387    }
388
389    /**
390     * @tests java.lang.Object#wait()
391     */
392    @TestTargetNew(
393        level = TestLevel.COMPLETE,
394        notes = "",
395        method = "wait",
396        args = {}
397    )
398    public void test_wait() {
399        // Test for method void java.lang.Object.wait()
400
401        // Inner class to run test thread.
402        class TestThread implements Runnable {
403            public void run() {
404                synchronized (obj1) {
405                    try {
406                        obj1.wait();// Wait for ever.
407                        status = 1;
408                    } catch (InterruptedException ex) {
409                        status = -1;
410                    }
411                }
412            }
413        }
414
415
416        // Start of test code.
417
418        // Warning:
419        // This code relies on threads getting serviced within
420        // 1 second of when they are notified. Although this
421        // seems reasonable, it could lead to false-failures.
422
423        status = 0;
424        new Thread(new TestThread()).start();
425        synchronized (obj1) {
426            try {
427                obj1.wait(1000, 0);
428                assertTrue("Thread woke too early. (status = " + status + ")",
429                        status == 0);
430                obj1.notifyAll();
431                obj1.wait(1000, 0);
432                assertTrue("Thread did not get notified. (status = " + status
433                        + ")", status == 1);
434            } catch (InterruptedException ex) {
435                fail(
436                        "Unexpectedly got an InterruptedException. (status = "
437                                + status + ")");
438            }
439        }
440
441        try {
442            Object obj = new Object();
443            obj.wait();
444            fail("IllegalMonitorStateException was not thrown.");
445        } catch(IllegalMonitorStateException imse) {
446            //expected
447        } catch(InterruptedException ex) {
448            fail("InterruptedException was thrown.");
449        }
450
451       try {
452           thr1 = new TestThread1(TestThread1.CASE_WAIT);
453           thr2 = new TestThread2();
454           thr1.start();
455           thr2.start();
456           thr2.join();
457           thr1.join();
458           thr1 = null;
459           thr2 = null;
460        } catch(InterruptedException e) {
461            fail("InterruptedException was thrown.");
462        }
463        assertEquals(3, status);
464    }
465
466    class TestThread1 extends Thread {
467
468        static final int CASE_WAIT = 0;
469        static final int CASE_WAIT_LONG = 1;
470        static final int CASE_WAIT_LONG_INT = 2;
471
472        int testCase = CASE_WAIT;
473
474        public TestThread1(int option) {
475            testCase = option;
476        }
477
478        public void run() {
479            synchronized (obj1) {
480                try {
481                    switch(testCase) {
482                        case CASE_WAIT:
483                            obj1.wait();// Wait for ever.
484                            break;
485                        case CASE_WAIT_LONG:
486                            obj1.wait(5000L);
487                            break;
488                        case CASE_WAIT_LONG_INT:
489                            obj1.wait(10000L, 999999);
490                            break;
491                    }
492
493                } catch (InterruptedException ex) {
494                    status = 3;
495                }
496            }
497        }
498    }
499
500    class TestThread2 extends Thread {
501        public void run() {
502            thr1.interrupt();
503        }
504    }
505
506    /**
507     * @tests java.lang.Object#wait(long)
508     */
509    @TestTargetNew(
510        level = TestLevel.COMPLETE,
511        notes = "",
512        method = "wait",
513        args = {long.class}
514    )
515    public void test_waitJ() {
516        // Test for method void java.lang.Object.wait(long)
517
518        // Start of test code.
519
520        final int loopCount = 20;
521        final int allowableError = 100; // millesconds
522        final int delay = 200; // milliseconds
523        synchronized (obj1) {
524            try {
525                int count = 0;
526                long[][] toLong = new long[3][3];
527                for (int i = 0; i < loopCount; ++i) {
528                    long before = System.currentTimeMillis();
529                    obj1.wait(delay, 0);
530                    long after = System.currentTimeMillis();
531                    long error = (after - before - delay);
532                    if (error < 0)
533                        error = -error;
534                    if (i > 0 && error > allowableError) {
535                        // Allow jit to warm up before testing
536                        if (count < toLong.length) {
537                            toLong[count][0] = i;
538                            toLong[count][1] = before;
539                            toLong[count][2] = after;
540                            count++;
541                        }
542                        if (error > (1000 + delay) || count == toLong.length) {
543                            StringBuffer sb = new StringBuffer();
544                            for (int j = 0; j < count; j++) {
545                                sb
546                                        .append("wakeup time too inaccurate, iteration ");
547                                sb.append(toLong[j][0]);
548                                sb.append(", before: ");
549                                sb.append(toLong[j][1]);
550                                sb.append(" after: ");
551                                sb.append(toLong[j][2]);
552                                sb.append(" diff: ");
553                                sb.append(toLong[j][2] - toLong[j][1]);
554                                sb.append("\n");
555                            }
556                            fail(sb.toString());
557                        }
558                    }
559                }
560            } catch (InterruptedException ex) {
561                fail(
562                        "Unexpectedly got an InterruptedException. (status = "
563                                + status + ")");
564            }
565        }
566
567        try {
568            Object obj = new Object();
569            obj.wait(5000L);
570            fail("IllegalMonitorStateException was not thrown.");
571        } catch(IllegalMonitorStateException imse) {
572            //expected
573        } catch(InterruptedException ex) {
574            fail("InterruptedException was thrown.");
575        }
576
577       try {
578           thr1 = new TestThread1(TestThread1.CASE_WAIT_LONG);
579           thr2 = new TestThread2();
580           thr1.start();
581           thr2.start();
582           thr2.join();
583           thr1.join();
584           thr1 = null;
585           thr2 = null;
586        } catch(InterruptedException e) {
587            fail("InterruptedException was thrown.");
588        }
589        assertEquals(3, status);
590    }
591
592    /**
593     * @tests java.lang.Object#wait(long, int)
594     */
595    @TestTargetNew(
596        level = TestLevel.COMPLETE,
597        notes = "",
598        method = "wait",
599        args = {long.class, int.class}
600    )
601    public void test_waitJI() {
602        // Test for method void java.lang.Object.wait(long, int)
603
604        // Inner class to run test thread.
605        class TestThread implements Runnable {
606            public void run() {
607                synchronized (obj1) {
608                    try {
609                        obj1.wait(0, 1); // Don't wait very long.
610                        status = 1;
611                        obj1.wait(0, 0); // Wait for ever.
612                        status = 2;
613                    } catch (InterruptedException ex) {
614                        status = -1;
615                    }
616                }
617            }
618        }
619
620
621        // Start of test code.
622
623        // Warning:
624        // This code relies on threads getting serviced within
625        // 1 second of when they are notified. Although this
626        // seems reasonable, it could lead to false-failures.
627
628        status = 0;
629        new Thread(new TestThread()).start();
630        synchronized (obj1) {
631            try {
632                obj1.wait(1000, 0);
633                assertTrue("Thread did not wake after 1 ms. (status = "
634                        + status + ")", status == 1);
635                obj1.notifyAll();
636                obj1.wait(1000, 0);
637                assertTrue("Thread did not get notified. (status = " + status
638                        + ")", status == 2);
639            } catch (InterruptedException ex) {
640                fail(
641                        "Unexpectedly got an InterruptedException. (status = "
642                                + status + ")");
643            }
644        }
645
646        try {
647            Object obj = new Object();
648            obj.wait(5000L, 1);
649            fail("IllegalMonitorStateException was not thrown.");
650        } catch(IllegalMonitorStateException imse) {
651            //expected
652        } catch(InterruptedException ex) {
653            fail("InterruptedException was thrown.");
654        }
655
656       try {
657           thr1 = new TestThread1(TestThread1.CASE_WAIT_LONG_INT);
658           thr2 = new TestThread2();
659           thr1.start();
660           thr2.start();
661           thr2.join();
662           thr1.join();
663           thr1 = null;
664           thr2 = null;
665        } catch(InterruptedException e) {
666            fail("InterruptedException was thrown.");
667        }
668        assertEquals(3, status);
669
670    }
671}
672