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 */ 17 18 package org.apache.harmony.luni.tests.java.lang; 19 20 import junit.framework.TestCase; 21 22 public class ThreadLocalTest extends TestCase { 23 24 /** 25 * @tests java.lang.ThreadLocal#ThreadLocal() 26 */ 27 public void test_Constructor() { 28 new ThreadLocal<Object>(); 29 } 30 31 /** 32 * @tests java.lang.ThreadLocal#remove() 33 */ 34 public void test_remove() { 35 ThreadLocal<String> tl = new ThreadLocal<String>() { 36 @Override 37 protected String initialValue() { 38 return "initial"; 39 } 40 }; 41 42 assertEquals("initial", tl.get()); 43 tl.set("fixture"); 44 assertEquals("fixture", tl.get()); 45 tl.remove(); 46 assertEquals("initial", tl.get()); 47 } 48 49 /** 50 * @tests java.lang.ThreadLocal#get() 51 */ 52 public void test_get() { 53 // Test for method java.lang.Object java.lang.ThreadLocal.get() 54 ThreadLocal<Object> l = new ThreadLocal<Object>(); 55 assertNull("ThreadLocal's initial value is null", l.get()); 56 57 // The ThreadLocal has to run once for each thread that touches the 58 // ThreadLocal 59 final Object INITIAL_VALUE = "'foo'"; 60 final ThreadLocal<Object> l1 = new ThreadLocal<Object>() { 61 @Override 62 protected Object initialValue() { 63 return INITIAL_VALUE; 64 } 65 }; 66 67 assertTrue("ThreadLocal's initial value should be " + INITIAL_VALUE 68 + " but is " + l1.get(), l1.get() == INITIAL_VALUE); 69 70 // We need this because inner types cannot assign to variables in 71 // container method. But assigning to object slots in the container 72 // method is ok. 73 class ResultSlot { 74 public Object result = null; 75 } 76 77 final ResultSlot THREADVALUE = new ResultSlot(); 78 Thread t = new Thread() { 79 @Override 80 public void run() { 81 THREADVALUE.result = l1.get(); 82 } 83 }; 84 85 // Wait for the other Thread assign what it observes as the value of the 86 // variable 87 t.start(); 88 try { 89 t.join(); 90 } catch (InterruptedException ie) { 91 fail("Interrupted!!"); 92 } 93 94 assertTrue("ThreadLocal's initial value in other Thread should be " 95 + INITIAL_VALUE, THREADVALUE.result == INITIAL_VALUE); 96 97 /* Regression test for implementation vulnerability reported 98 * on Harmony dev list. 99 */ 100 ThreadLocal<Object> thrVar = new ThreadLocal<Object>() { 101 public int hashCode() { 102 fail("ThreadLocal should not be asked for it's hashCode"); 103 return 0; // never reached 104 } 105 }; 106 thrVar.get(); 107 } 108 109 /** 110 * @tests java.lang.ThreadLocal#set(java.lang.Object) 111 */ 112 public void test_setLjava_lang_Object() { 113 // Test for method void java.lang.ThreadLocal.set(java.lang.Object) 114 115 final Object OBJ = new Object(); 116 final ThreadLocal<Object> l = new ThreadLocal<Object>(); 117 l.set(OBJ); 118 assertTrue("ThreadLocal's initial value is " + OBJ, l.get() == OBJ); 119 120 // We need this because inner types cannot assign to variables in 121 // container method. 122 // But assigning to object slots in the container method is ok. 123 class ResultSlot { 124 public Object result = null; 125 } 126 127 final ResultSlot THREADVALUE = new ResultSlot(); 128 Thread t = new Thread() { 129 @Override 130 public void run() { 131 THREADVALUE.result = l.get(); 132 } 133 }; 134 135 // Wait for the other Thread assign what it observes as the value of the 136 // variable 137 t.start(); 138 try { 139 t.join(); 140 } catch (InterruptedException ie) { 141 fail("Interrupted!!"); 142 } 143 144 // ThreadLocal is not inherited, so the other Thread should see it as 145 // null 146 assertNull("ThreadLocal's value in other Thread should be null", 147 THREADVALUE.result); 148 149 } 150 } 151