blob: 659a839e1a3cfd49de85aded31a739b5113b4b89 [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 dalvik.annotation.TestTargets;
import dalvik.annotation.TestLevel;
import dalvik.annotation.TestTargetNew;
import dalvik.annotation.TestTargetClass;
import junit.framework.TestCase;
@TestTargetClass(ThreadLocal.class)
public class ThreadLocalTest extends TestCase {
/**
* @tests java.lang.ThreadLocal#ThreadLocal()
*/
@TestTargetNew(
level = TestLevel.COMPLETE,
notes = "",
method = "ThreadLocal",
args = {}
)
public void test_Constructor() {
new ThreadLocal<Object>();
}
/**
* @tests java.lang.ThreadLocal#remove()
*/
@TestTargetNew(
level = TestLevel.COMPLETE,
notes = "",
method = "remove",
args = {}
)
public void test_remove() {
ThreadLocal<String> tl = new ThreadLocal<String>() {
@Override
protected String initialValue() {
return "initial";
}
};
assertEquals("initial", tl.get());
tl.set("fixture");
assertEquals("fixture", tl.get());
tl.remove();
assertEquals("initial", tl.get());
}
/**
* @tests java.lang.ThreadLocal#get()
*/
@TestTargetNew(
level = TestLevel.COMPLETE,
notes = "",
method = "get",
args = {}
)
public void test_get() {
// Test for method java.lang.Object java.lang.ThreadLocal.get()
ThreadLocal<Object> l = new ThreadLocal<Object>();
assertNull("ThreadLocal's initial value is null", l.get());
// The ThreadLocal has to run once for each thread that touches the
// ThreadLocal
final Object INITIAL_VALUE = "'foo'";
final ThreadLocal<Object> l1 = new ThreadLocal<Object>() {
@Override
protected Object initialValue() {
return INITIAL_VALUE;
}
};
assertTrue("ThreadLocal's initial value should be " + INITIAL_VALUE
+ " but is " + l1.get(), l1.get() == INITIAL_VALUE);
// We need this because inner types cannot assign to variables in
// container method. But assigning to object slots in the container
// method is ok.
class ResultSlot {
public Object result = null;
}
final ResultSlot THREADVALUE = new ResultSlot();
Thread t = new Thread() {
@Override
public void run() {
THREADVALUE.result = l1.get();
}
};
// Wait for the other Thread assign what it observes as the value of the
// variable
t.start();
try {
t.join();
} catch (InterruptedException ie) {
fail("Interrupted!!");
}
assertTrue("ThreadLocal's initial value in other Thread should be "
+ INITIAL_VALUE, THREADVALUE.result == INITIAL_VALUE);
/* Regression test for implementation vulnerability reported
* on Harmony dev list.
*/
ThreadLocal<Object> thrVar = new ThreadLocal<Object>() {
public int hashCode() {
fail("ThreadLocal should not be asked for it's hashCode");
return 0; // never reached
}
};
thrVar.get();
}
/**
* @tests java.lang.ThreadLocal#set(java.lang.Object)
*/
@TestTargetNew(
level = TestLevel.COMPLETE,
notes = "",
method = "set",
args = {java.lang.Object.class}
)
public void test_setLjava_lang_Object() {
// Test for method void java.lang.ThreadLocal.set(java.lang.Object)
final Object OBJ = new Object();
final ThreadLocal<Object> l = new ThreadLocal<Object>();
l.set(OBJ);
assertTrue("ThreadLocal's initial value is " + OBJ, l.get() == OBJ);
// We need this because inner types cannot assign to variables in
// container method.
// But assigning to object slots in the container method is ok.
class ResultSlot {
public Object result = null;
}
final ResultSlot THREADVALUE = new ResultSlot();
Thread t = new Thread() {
@Override
public void run() {
THREADVALUE.result = l.get();
}
};
// Wait for the other Thread assign what it observes as the value of the
// variable
t.start();
try {
t.join();
} catch (InterruptedException ie) {
fail("Interrupted!!");
}
// ThreadLocal is not inherited, so the other Thread should see it as
// null
assertNull("ThreadLocal's value in other Thread should be null",
THREADVALUE.result);
}
/**
* @tests java.lang.InheritableThreadLocal
*/
@TestTargetNew(
level = TestLevel.COMPLETE,
notes = "",
method = "get",
args = {}
)
public void test_Ljava_lang_InheritableThreadLocal()
throws InterruptedException {
final Object value = new Object();
final Object inheritedValue = new Object();
final ThreadLocal<Object> threadLocal
= new InheritableThreadLocal<Object>() {
@Override
protected Object childValue(Object parentValue) {
assertSame(value, parentValue);
return inheritedValue;
}
};
threadLocal.set(value);
final Object[] holder = new Object[1];
Thread thread = new Thread() {
public void run() {
holder[0] = threadLocal.get();
}
};
thread.start();
thread.join();
assertSame(value, threadLocal.get());
assertSame(inheritedValue, holder[0]);
// Cleanup properly, so other tests are not affected.
threadLocal.remove();
}
}