001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017:
018: package org.apache.harmony.luni.tests.java.lang;
019:
020: import junit.framework.TestCase;
021:
022: public class ThreadLocalTest extends TestCase {
023:
024: /**
025: * @tests java.lang.ThreadLocal#ThreadLocal()
026: */
027: public void test_Constructor() {
028: new ThreadLocal<Object>();
029: }
030:
031: /**
032: * @tests java.lang.ThreadLocal#remove()
033: */
034: public void test_remove() {
035: ThreadLocal<String> tl = new ThreadLocal<String>() {
036: @Override
037: protected String initialValue() {
038: return "initial";
039: }
040: };
041:
042: assertEquals("initial", tl.get());
043: tl.set("fixture");
044: assertEquals("fixture", tl.get());
045: tl.remove();
046: assertEquals("initial", tl.get());
047: }
048:
049: /**
050: * @tests java.lang.ThreadLocal#get()
051: */
052: public void test_get() {
053: // Test for method java.lang.Object java.lang.ThreadLocal.get()
054: ThreadLocal<Object> l = new ThreadLocal<Object>();
055: assertNull("ThreadLocal's initial value is null", l.get());
056:
057: // The ThreadLocal has to run once for each thread that touches the
058: // ThreadLocal
059: final Object INITIAL_VALUE = "'foo'";
060: final ThreadLocal<Object> l1 = new ThreadLocal<Object>() {
061: @Override
062: protected Object initialValue() {
063: return INITIAL_VALUE;
064: }
065: };
066:
067: assertTrue("ThreadLocal's initial value should be "
068: + INITIAL_VALUE + " but is " + l1.get(),
069: l1.get() == INITIAL_VALUE);
070:
071: // We need this because inner types cannot assign to variables in
072: // container method. But assigning to object slots in the container
073: // method is ok.
074: class ResultSlot {
075: public Object result = null;
076: }
077:
078: final ResultSlot THREADVALUE = new ResultSlot();
079: Thread t = new Thread() {
080: @Override
081: public void run() {
082: THREADVALUE.result = l1.get();
083: }
084: };
085:
086: // Wait for the other Thread assign what it observes as the value of the
087: // variable
088: t.start();
089: try {
090: t.join();
091: } catch (InterruptedException ie) {
092: fail("Interrupted!!");
093: }
094:
095: assertTrue(
096: "ThreadLocal's initial value in other Thread should be "
097: + INITIAL_VALUE,
098: THREADVALUE.result == INITIAL_VALUE);
099:
100: /* Regression test for implementation vulnerability reported
101: * on Harmony dev list.
102: */
103: ThreadLocal<Object> thrVar = new ThreadLocal<Object>() {
104: public int hashCode() {
105: fail("ThreadLocal should not be asked for it's hashCode");
106: return 0; // never reached
107: }
108: };
109: thrVar.get();
110: }
111:
112: /**
113: * @tests java.lang.ThreadLocal#set(java.lang.Object)
114: */
115: public void test_setLjava_lang_Object() {
116: // Test for method void java.lang.ThreadLocal.set(java.lang.Object)
117:
118: final Object OBJ = new Object();
119: final ThreadLocal<Object> l = new ThreadLocal<Object>();
120: l.set(OBJ);
121: assertTrue("ThreadLocal's initial value is " + OBJ,
122: l.get() == OBJ);
123:
124: // We need this because inner types cannot assign to variables in
125: // container method.
126: // But assigning to object slots in the container method is ok.
127: class ResultSlot {
128: public Object result = null;
129: }
130:
131: final ResultSlot THREADVALUE = new ResultSlot();
132: Thread t = new Thread() {
133: @Override
134: public void run() {
135: THREADVALUE.result = l.get();
136: }
137: };
138:
139: // Wait for the other Thread assign what it observes as the value of the
140: // variable
141: t.start();
142: try {
143: t.join();
144: } catch (InterruptedException ie) {
145: fail("Interrupted!!");
146: }
147:
148: // ThreadLocal is not inherited, so the other Thread should see it as
149: // null
150: assertNull(
151: "ThreadLocal's value in other Thread should be null",
152: THREADVALUE.result);
153:
154: }
155: }
|