/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.harmony.luni.tests.java.lang; import java.util.Vector; //import dalvik.annotation.TestTargets; //import dalvik.annotation.TestLevel; //import dalvik.annotation.TestTargetNew; //import dalvik.annotation.TestTargetClass; //import dalvik.annotation.BrokenTest; //import dalvik.annotation.SideEffect; //@TestTargetClass(Object.class) public class ObjectTest extends junit.framework.TestCase { public boolean isCalled = false; /** * Test objects. */ Object obj1 = new Object(); Object obj2 = new Object(); /** * Generic state indicator. */ int status = 0; int ready = 0; TestThread1 thr1; TestThread2 thr2; /** * @tests java.lang.Object#Object() @TestTargetNew( level = TestLevel.COMPLETE, notes = "", method = "Object", args = {} ) */ public void test_Constructor() { // Test for method java.lang.Object() assertNotNull("Constructor failed !!!", new Object()); } /** * @tests java.lang.Object#equals(java.lang.Object) @TestTargetNew( level = TestLevel.COMPLETE, notes = "", method = "equals", args = {java.lang.Object.class} ) */ public void test_equalsLjava_lang_Object() { // Test for method boolean java.lang.Object.equals(java.lang.Object) assertTrue("Same object should be equal", obj1.equals(obj1)); assertTrue("Different objects should not be equal", !obj1.equals(obj2)); } /* @TestTargetNew( level = TestLevel.COMPLETE, notes = "", method = "finalize", args = {} ) @SideEffect("Causes OutOfMemoryError to test finalization") */ public void test_finalize() { isCalled = false; class TestObject extends Object { Vector<StringBuffer> v = new Vector<StringBuffer>(); public void add() { v.add(new StringBuffer(10000)); } protected void finalize() throws Throwable { isCalled = true; super.finalize(); } } TestObject to = new TestObject(); try { while(true) { to.add(); } } catch(OutOfMemoryError oome) { //expected to = null; } System.gc(); System.runFinalization(); assertTrue(isCalled); } /* @TestTargetNew( level = TestLevel.COMPLETE, notes = "", method = "clone", args = {} ) */ public void test_clone() { MockCloneableObject mco = new MockCloneableObject(); try { assertFalse(mco.equals(mco.clone())); assertEquals(mco.getClass(), mco.clone().getClass()); } catch(CloneNotSupportedException cnse) { fail("CloneNotSupportedException was thrown."); } MockObject mo = new MockObject(); try { mo.clone(); fail("CloneNotSupportedException was not thrown."); } catch(CloneNotSupportedException cnse) { //expected } } class MockCloneableObject extends Object implements Cloneable { public Object clone() throws CloneNotSupportedException { return super.clone(); } } class MockObject extends Object { boolean isCalled = false; public void finalize() throws Throwable { super.finalize(); isCalled = true; } public Object clone() throws CloneNotSupportedException { return super.clone(); } } /** * @tests java.lang.Object#getClass() @TestTargetNew( level = TestLevel.COMPLETE, notes = "", method = "getClass", args = {} ) */ public void test_getClass() { // Test for method java.lang.Class java.lang.Object.getClass() String classNames[] = { "java.lang.Object", "java.lang.Throwable", "java.lang.StringBuffer" }; Class<?> classToTest = null; Object instanceToTest = null; status = 0; for (int i = 0; i < classNames.length; ++i) { try { classToTest = Class.forName(classNames[i]); instanceToTest = classToTest.newInstance(); assertTrue("Instance didn't match creator class.", instanceToTest.getClass() == classToTest); assertTrue("Instance didn't match class with matching name.", instanceToTest.getClass() == Class .forName(classNames[i])); } catch (Exception ex) { fail("Unexpected exception : " + ex.getMessage()); } } } /** * @tests java.lang.Object#hashCode() @TestTargetNew( level = TestLevel.COMPLETE, notes = "", method = "hashCode", args = {} ) */ public void test_hashCode() { // Test for method int java.lang.Object.hashCode() assertTrue("Same object should have same hash.", obj1.hashCode() == obj1.hashCode()); assertTrue("Same object should have same hash.", obj2.hashCode() == obj2.hashCode()); } /** * @tests java.lang.Object#notify() @TestTargetNew( level = TestLevel.COMPLETE, notes = "", method = "notify", args = {} ) */ public void test_notify() { // Test for method void java.lang.Object.notify() // Inner class to run test thread. class TestThread implements Runnable { public void run() { synchronized (obj1) { try { ready += 1; obj1.wait();// Wait for ever. status += 1; } catch (InterruptedException ex) { status = -1000; } } } } ; // Start of test code. // Warning: // This code relies on each thread getting serviced within // 200 mSec of when it is notified. Although this // seems reasonable, it could lead to false-failures. ready = 0; status = 0; final int readyWaitSecs = 3; final int threadCount = 20; for (int i = 0; i < threadCount; ++i) { new Thread(new TestThread()).start(); } synchronized (obj1) { try { // Wait up to readyWaitSeconds for all threads to be waiting on // monitor for (int i = 0; i < readyWaitSecs; i++) { obj1.wait(1000, 0); if (ready == threadCount) { break; } } // Check pre-conditions of testing notifyAll assertTrue("Not all launched threads are waiting. (ready = " + ready + ")", ready == threadCount); assertTrue("Thread woke too early. (status = " + status + ")", status == 0); for (int i = 1; i <= threadCount; ++i) { obj1.notify(); obj1.wait(200, 0); assertTrue("Out of sync. (expected " + i + " but got " + status + ")", status == i); } } catch (InterruptedException ex) { fail( "Unexpectedly got an InterruptedException. (status = " + status + ")"); } } try { Object obj = new Object(); obj.notify(); fail("IllegalMonitorStateException was not thrown."); } catch(IllegalMonitorStateException imse) { //expected } } /** * @tests java.lang.Object#notifyAll() @TestTargetNew( level = TestLevel.COMPLETE, notes = "", method = "notifyAll", args = {} ) */ public void test_notifyAll() { // Test for method void java.lang.Object.notifyAll() // Inner class to run test thread. class TestThread implements Runnable { public void run() { synchronized (obj1) { try { ready += 1; obj1.wait();// Wait for ever. status += 1; } catch (InterruptedException ex) { status = -1000; } } } } ; // Start of test code. // Warning: // This code relies on all threads getting serviced within // 5 seconds of when they are notified. Although this // seems reasonable, it could lead to false-failures. status = 0; ready = 0; final int readyWaitSecs = 3; final int threadCount = 20; for (int i = 0; i < threadCount; ++i) { new Thread(new TestThread()).start(); } synchronized (obj1) { try { // Wait up to readyWaitSeconds for all threads to be waiting on // monitor for (int i = 0; i < readyWaitSecs; i++) { obj1.wait(1000, 0); if (ready == threadCount) { break; } } // Check pre-conditions of testing notifyAll assertTrue("Not all launched threads are waiting. (ready = " + ready + ")", ready == threadCount); assertTrue("At least one thread woke too early. (status = " + status + ")", status == 0); obj1.notifyAll(); obj1.wait(5000, 0); assertTrue( "At least one thread did not get notified. (status = " + status + ")", status == threadCount); } catch (InterruptedException ex) { fail( "Unexpectedly got an InterruptedException. (status = " + status + ")"); } } try { Object obj = new Object(); obj.notifyAll(); fail("IllegalMonitorStateException was not thrown."); } catch(IllegalMonitorStateException imse) { //expected } } /** * @tests java.lang.Object#toString() @TestTargetNew( level = TestLevel.COMPLETE, notes = "", method = "toString", args = {} ) */ public void test_toString() { // Test for method java.lang.String java.lang.Object.toString() assertNotNull("Object toString returned null.", obj1.toString()); } /** * @tests java.lang.Object#wait() @TestTargetNew( level = TestLevel.COMPLETE, notes = "", method = "wait", args = {} ) */ public void test_wait() { // Test for method void java.lang.Object.wait() // Inner class to run test thread. class TestThread implements Runnable { public void run() { synchronized (obj1) { try { obj1.wait();// Wait for ever. status = 1; } catch (InterruptedException ex) { status = -1; } } } } // Start of test code. // Warning: // This code relies on threads getting serviced within // 1 second of when they are notified. Although this // seems reasonable, it could lead to false-failures. status = 0; new Thread(new TestThread()).start(); synchronized (obj1) { try { obj1.wait(1000, 0); assertTrue("Thread woke too early. (status = " + status + ")", status == 0); obj1.notifyAll(); obj1.wait(1000, 0); assertTrue("Thread did not get notified. (status = " + status + ")", status == 1); } catch (InterruptedException ex) { fail( "Unexpectedly got an InterruptedException. (status = " + status + ")"); } } try { Object obj = new Object(); obj.wait(); fail("IllegalMonitorStateException was not thrown."); } catch(IllegalMonitorStateException imse) { //expected } catch(InterruptedException ex) { fail("InterruptedException was thrown."); } try { thr1 = new TestThread1(TestThread1.CASE_WAIT); thr2 = new TestThread2(); thr1.start(); thr2.start(); thr2.join(); thr1.join(); thr1 = null; thr2 = null; } catch(InterruptedException e) { fail("InterruptedException was thrown."); } assertEquals(3, status); } class TestThread1 extends Thread { static final int CASE_WAIT = 0; static final int CASE_WAIT_LONG = 1; static final int CASE_WAIT_LONG_INT = 2; int testCase = CASE_WAIT; public TestThread1(int option) { testCase = option; } public void run() { synchronized (obj1) { try { switch(testCase) { case CASE_WAIT: obj1.wait();// Wait for ever. break; case CASE_WAIT_LONG: obj1.wait(5000L); break; case CASE_WAIT_LONG_INT: obj1.wait(10000L, 999999); break; } } catch (InterruptedException ex) { status = 3; } } } } class TestThread2 extends Thread { public void run() { thr1.interrupt(); } } /** * @tests java.lang.Object#wait(long) @TestTargetNew( level = TestLevel.COMPLETE, notes = "", method = "wait", args = {long.class} ) */ public void test_waitJ() { // Test for method void java.lang.Object.wait(long) // Start of test code. final int loopCount = 20; final int allowableError = 100; // millesconds final int delay = 200; // milliseconds synchronized (obj1) { try { int count = 0; long[][] toLong = new long[3][3]; for (int i = 0; i < loopCount; ++i) { long before = System.currentTimeMillis(); obj1.wait(delay, 0); long after = System.currentTimeMillis(); long error = (after - before - delay); if (error < 0) error = -error; if (i > 0 && error > allowableError) { // Allow jit to warm up before testing if (count < toLong.length) { toLong[count][0] = i; toLong[count][1] = before; toLong[count][2] = after; count++; } if (error > (1000 + delay) || count == toLong.length) { StringBuffer sb = new StringBuffer(); for (int j = 0; j < count; j++) { sb .append("wakeup time too inaccurate, iteration "); sb.append(toLong[j][0]); sb.append(", before: "); sb.append(toLong[j][1]); sb.append(" after: "); sb.append(toLong[j][2]); sb.append(" diff: "); sb.append(toLong[j][2] - toLong[j][1]); sb.append("\n"); } fail(sb.toString()); } } } } catch (InterruptedException ex) { fail( "Unexpectedly got an InterruptedException. (status = " + status + ")"); } } try { Object obj = new Object(); obj.wait(5000L); fail("IllegalMonitorStateException was not thrown."); } catch(IllegalMonitorStateException imse) { //expected } catch(InterruptedException ex) { fail("InterruptedException was thrown."); } try { thr1 = new TestThread1(TestThread1.CASE_WAIT_LONG); thr2 = new TestThread2(); thr1.start(); thr2.start(); thr2.join(); thr1.join(); thr1 = null; thr2 = null; } catch(InterruptedException e) { fail("InterruptedException was thrown."); } assertEquals(3, status); } /** * @tests java.lang.Object#wait(long, int) @TestTargetNew( level = TestLevel.COMPLETE, notes = "", method = "wait", args = {long.class, int.class} ) */ public void test_waitJI() { // Test for method void java.lang.Object.wait(long, int) // Inner class to run test thread. class TestThread implements Runnable { public void run() { synchronized (obj1) { try { obj1.wait(0, 1); // Don't wait very long. status = 1; obj1.wait(0, 0); // Wait for ever. status = 2; } catch (InterruptedException ex) { status = -1; } } } } // Start of test code. // Warning: // This code relies on threads getting serviced within // 1 second of when they are notified. Although this // seems reasonable, it could lead to false-failures. status = 0; new Thread(new TestThread()).start(); synchronized (obj1) { try { obj1.wait(1000, 0); assertTrue("Thread did not wake after 1 ms. (status = " + status + ")", status == 1); obj1.notifyAll(); obj1.wait(1000, 0); assertTrue("Thread did not get notified. (status = " + status + ")", status == 2); } catch (InterruptedException ex) { fail( "Unexpectedly got an InterruptedException. (status = " + status + ")"); } } try { Object obj = new Object(); obj.wait(5000L, 1); fail("IllegalMonitorStateException was not thrown."); } catch(IllegalMonitorStateException imse) { //expected } catch(InterruptedException ex) { fail("InterruptedException was thrown."); } try { thr1 = new TestThread1(TestThread1.CASE_WAIT_LONG_INT); thr2 = new TestThread2(); thr1.start(); thr2.start(); thr2.join(); thr1.join(); thr1 = null; thr2 = null; } catch(InterruptedException e) { fail("InterruptedException was thrown."); } assertEquals(3, status); } }