Home | History | Annotate | Download | only in lang
      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