1 /*
2  * Written by Doug Lea with assistance from members of JCP JSR-166
3  * Expert Group and released to the public domain, as explained at
4  * http://creativecommons.org/publicdomain/zero/1.0/
5  * Other contributors include Andrew Wright, Jeffrey Hayes,
6  * Pat Fisher, Mike Judd.
7  */
8 
9 package jsr166;
10 
11 import java.util.Arrays;
12 import java.util.concurrent.atomic.AtomicReferenceArray;
13 
14 import junit.framework.Test;
15 import junit.framework.TestSuite;
16 
17 public class AtomicReferenceArrayTest extends JSR166TestCase {
18     // android-note: Removed because the CTS runner does a bad job of
19     // retrying tests that have suite() declarations.
20     //
21     // public static void main(String[] args) {
22     //     main(suite(), args);
23     // }
24     // public static Test suite() {
25     //     return new TestSuite(AtomicReferenceArrayTest.class);
26     // }
27 
28     /**
29      * constructor creates array of given size with all elements null
30      */
testConstructor()31     public void testConstructor() {
32         AtomicReferenceArray<Integer> aa = new AtomicReferenceArray<Integer>(SIZE);
33         for (int i = 0; i < SIZE; i++) {
34             assertNull(aa.get(i));
35         }
36     }
37 
38     /**
39      * constructor with null array throws NPE
40      */
testConstructor2NPE()41     public void testConstructor2NPE() {
42         try {
43             Integer[] a = null;
44             new AtomicReferenceArray<Integer>(a);
45             shouldThrow();
46         } catch (NullPointerException success) {}
47     }
48 
49     /**
50      * constructor with array is of same size and has all elements
51      */
testConstructor2()52     public void testConstructor2() {
53         Integer[] a = { two, one, three, four, seven };
54         AtomicReferenceArray<Integer> aa = new AtomicReferenceArray<Integer>(a);
55         assertEquals(a.length, aa.length());
56         for (int i = 0; i < a.length; i++)
57             assertEquals(a[i], aa.get(i));
58     }
59 
60     /**
61      * Initialize AtomicReferenceArray<Class> with SubClass[]
62      */
testConstructorSubClassArray()63     public void testConstructorSubClassArray() {
64         Integer[] a = { two, one, three, four, seven };
65         AtomicReferenceArray<Number> aa = new AtomicReferenceArray<Number>(a);
66         assertEquals(a.length, aa.length());
67         for (int i = 0; i < a.length; i++) {
68             assertSame(a[i], aa.get(i));
69             Long x = Long.valueOf(i);
70             aa.set(i, x);
71             assertSame(x, aa.get(i));
72         }
73     }
74 
75     /**
76      * get and set for out of bound indices throw IndexOutOfBoundsException
77      */
testIndexing()78     public void testIndexing() {
79         AtomicReferenceArray<Integer> aa = new AtomicReferenceArray<Integer>(SIZE);
80         for (int index : new int[] { -1, SIZE }) {
81             try {
82                 aa.get(index);
83                 shouldThrow();
84             } catch (IndexOutOfBoundsException success) {}
85             try {
86                 aa.set(index, null);
87                 shouldThrow();
88             } catch (IndexOutOfBoundsException success) {}
89             try {
90                 aa.lazySet(index, null);
91                 shouldThrow();
92             } catch (IndexOutOfBoundsException success) {}
93             try {
94                 aa.compareAndSet(index, null, null);
95                 shouldThrow();
96             } catch (IndexOutOfBoundsException success) {}
97             try {
98                 aa.weakCompareAndSet(index, null, null);
99                 shouldThrow();
100             } catch (IndexOutOfBoundsException success) {}
101         }
102     }
103 
104     /**
105      * get returns the last value set at index
106      */
testGetSet()107     public void testGetSet() {
108         AtomicReferenceArray aa = new AtomicReferenceArray(SIZE);
109         for (int i = 0; i < SIZE; i++) {
110             aa.set(i, one);
111             assertSame(one, aa.get(i));
112             aa.set(i, two);
113             assertSame(two, aa.get(i));
114             aa.set(i, m3);
115             assertSame(m3, aa.get(i));
116         }
117     }
118 
119     /**
120      * get returns the last value lazySet at index by same thread
121      */
testGetLazySet()122     public void testGetLazySet() {
123         AtomicReferenceArray aa = new AtomicReferenceArray(SIZE);
124         for (int i = 0; i < SIZE; i++) {
125             aa.lazySet(i, one);
126             assertSame(one, aa.get(i));
127             aa.lazySet(i, two);
128             assertSame(two, aa.get(i));
129             aa.lazySet(i, m3);
130             assertSame(m3, aa.get(i));
131         }
132     }
133 
134     /**
135      * compareAndSet succeeds in changing value if equal to expected else fails
136      */
testCompareAndSet()137     public void testCompareAndSet() {
138         AtomicReferenceArray aa = new AtomicReferenceArray(SIZE);
139         for (int i = 0; i < SIZE; i++) {
140             aa.set(i, one);
141             assertTrue(aa.compareAndSet(i, one, two));
142             assertTrue(aa.compareAndSet(i, two, m4));
143             assertSame(m4, aa.get(i));
144             assertFalse(aa.compareAndSet(i, m5, seven));
145             assertSame(m4, aa.get(i));
146             assertTrue(aa.compareAndSet(i, m4, seven));
147             assertSame(seven, aa.get(i));
148         }
149     }
150 
151     /**
152      * compareAndSet in one thread enables another waiting for value
153      * to succeed
154      */
testCompareAndSetInMultipleThreads()155     public void testCompareAndSetInMultipleThreads() throws InterruptedException {
156         final AtomicReferenceArray a = new AtomicReferenceArray(1);
157         a.set(0, one);
158         Thread t = new Thread(new CheckedRunnable() {
159             public void realRun() {
160                 while (!a.compareAndSet(0, two, three))
161                     Thread.yield();
162             }});
163 
164         t.start();
165         assertTrue(a.compareAndSet(0, one, two));
166         t.join(LONG_DELAY_MS);
167         assertFalse(t.isAlive());
168         assertSame(three, a.get(0));
169     }
170 
171     /**
172      * repeated weakCompareAndSet succeeds in changing value when equal
173      * to expected
174      */
testWeakCompareAndSet()175     public void testWeakCompareAndSet() {
176         AtomicReferenceArray aa = new AtomicReferenceArray(SIZE);
177         for (int i = 0; i < SIZE; i++) {
178             aa.set(i, one);
179             do {} while (!aa.weakCompareAndSet(i, one, two));
180             do {} while (!aa.weakCompareAndSet(i, two, m4));
181             assertSame(m4, aa.get(i));
182             do {} while (!aa.weakCompareAndSet(i, m4, seven));
183             assertSame(seven, aa.get(i));
184         }
185     }
186 
187     /**
188      * getAndSet returns previous value and sets to given value at given index
189      */
testGetAndSet()190     public void testGetAndSet() {
191         AtomicReferenceArray aa = new AtomicReferenceArray(SIZE);
192         for (int i = 0; i < SIZE; i++) {
193             aa.set(i, one);
194             assertSame(one, aa.getAndSet(i, zero));
195             assertSame(zero, aa.getAndSet(i, m10));
196             assertSame(m10, aa.getAndSet(i, one));
197         }
198     }
199 
200     /**
201      * a deserialized serialized array holds same values
202      */
testSerialization()203     public void testSerialization() throws Exception {
204         AtomicReferenceArray x = new AtomicReferenceArray(SIZE);
205         for (int i = 0; i < SIZE; i++) {
206             x.set(i, new Integer(-i));
207         }
208         AtomicReferenceArray y = serialClone(x);
209         assertNotSame(x, y);
210         assertEquals(x.length(), y.length());
211         for (int i = 0; i < SIZE; i++) {
212             assertEquals(x.get(i), y.get(i));
213         }
214     }
215 
216     /**
217      * toString returns current value.
218      */
testToString()219     public void testToString() {
220         Integer[] a = { two, one, three, four, seven };
221         AtomicReferenceArray<Integer> aa = new AtomicReferenceArray<Integer>(a);
222         assertEquals(Arrays.toString(a), aa.toString());
223     }
224 }
225