blob: 2b3c3f3d9cae074e45faab53178b9c8a8fc570a1 [file] [log] [blame]
/*
* 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);
}
}