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
9package jsr166;
10
11import java.util.concurrent.atomic.AtomicInteger;
12
13import junit.framework.Test;
14import junit.framework.TestSuite;
15
16public class AtomicIntegerTest extends JSR166TestCase {
17    // android-note: Removed because the CTS runner does a bad job of
18    // retrying tests that have suite() declarations.
19    //
20    // public static void main(String[] args) {
21    //     main(suite(), args);
22    // }
23    // public static Test suite() {
24    //     return new TestSuite(AtomicIntegerTest.class);
25    // }
26
27    final int[] VALUES = {
28        Integer.MIN_VALUE, -1, 0, 1, 42, Integer.MAX_VALUE,
29    };
30
31    /**
32     * constructor initializes to given value
33     */
34    public void testConstructor() {
35        AtomicInteger ai = new AtomicInteger(1);
36        assertEquals(1, ai.get());
37    }
38
39    /**
40     * default constructed initializes to zero
41     */
42    public void testConstructor2() {
43        AtomicInteger ai = new AtomicInteger();
44        assertEquals(0, ai.get());
45    }
46
47    /**
48     * get returns the last value set
49     */
50    public void testGetSet() {
51        AtomicInteger ai = new AtomicInteger(1);
52        assertEquals(1, ai.get());
53        ai.set(2);
54        assertEquals(2, ai.get());
55        ai.set(-3);
56        assertEquals(-3, ai.get());
57    }
58
59    /**
60     * get returns the last value lazySet in same thread
61     */
62    public void testGetLazySet() {
63        AtomicInteger ai = new AtomicInteger(1);
64        assertEquals(1, ai.get());
65        ai.lazySet(2);
66        assertEquals(2, ai.get());
67        ai.lazySet(-3);
68        assertEquals(-3, ai.get());
69    }
70
71    /**
72     * compareAndSet succeeds in changing value if equal to expected else fails
73     */
74    public void testCompareAndSet() {
75        AtomicInteger ai = new AtomicInteger(1);
76        assertTrue(ai.compareAndSet(1, 2));
77        assertTrue(ai.compareAndSet(2, -4));
78        assertEquals(-4, ai.get());
79        assertFalse(ai.compareAndSet(-5, 7));
80        assertEquals(-4, ai.get());
81        assertTrue(ai.compareAndSet(-4, 7));
82        assertEquals(7, ai.get());
83    }
84
85    /**
86     * compareAndSet in one thread enables another waiting for value
87     * to succeed
88     */
89    public void testCompareAndSetInMultipleThreads() throws Exception {
90        final AtomicInteger ai = new AtomicInteger(1);
91        Thread t = new Thread(new CheckedRunnable() {
92            public void realRun() {
93                while (!ai.compareAndSet(2, 3))
94                    Thread.yield();
95            }});
96
97        t.start();
98        assertTrue(ai.compareAndSet(1, 2));
99        t.join(LONG_DELAY_MS);
100        assertFalse(t.isAlive());
101        assertEquals(3, ai.get());
102    }
103
104    /**
105     * repeated weakCompareAndSet succeeds in changing value when equal
106     * to expected
107     */
108    public void testWeakCompareAndSet() {
109        AtomicInteger ai = new AtomicInteger(1);
110        do {} while (!ai.weakCompareAndSet(1, 2));
111        do {} while (!ai.weakCompareAndSet(2, -4));
112        assertEquals(-4, ai.get());
113        do {} while (!ai.weakCompareAndSet(-4, 7));
114        assertEquals(7, ai.get());
115    }
116
117    /**
118     * getAndSet returns previous value and sets to given value
119     */
120    public void testGetAndSet() {
121        AtomicInteger ai = new AtomicInteger(1);
122        assertEquals(1, ai.getAndSet(0));
123        assertEquals(0, ai.getAndSet(-10));
124        assertEquals(-10, ai.getAndSet(1));
125    }
126
127    /**
128     * getAndAdd returns previous value and adds given value
129     */
130    public void testGetAndAdd() {
131        AtomicInteger ai = new AtomicInteger(1);
132        assertEquals(1, ai.getAndAdd(2));
133        assertEquals(3, ai.get());
134        assertEquals(3, ai.getAndAdd(-4));
135        assertEquals(-1, ai.get());
136    }
137
138    /**
139     * getAndDecrement returns previous value and decrements
140     */
141    public void testGetAndDecrement() {
142        AtomicInteger ai = new AtomicInteger(1);
143        assertEquals(1, ai.getAndDecrement());
144        assertEquals(0, ai.getAndDecrement());
145        assertEquals(-1, ai.getAndDecrement());
146    }
147
148    /**
149     * getAndIncrement returns previous value and increments
150     */
151    public void testGetAndIncrement() {
152        AtomicInteger ai = new AtomicInteger(1);
153        assertEquals(1, ai.getAndIncrement());
154        assertEquals(2, ai.get());
155        ai.set(-2);
156        assertEquals(-2, ai.getAndIncrement());
157        assertEquals(-1, ai.getAndIncrement());
158        assertEquals(0, ai.getAndIncrement());
159        assertEquals(1, ai.get());
160    }
161
162    /**
163     * addAndGet adds given value to current, and returns current value
164     */
165    public void testAddAndGet() {
166        AtomicInteger ai = new AtomicInteger(1);
167        assertEquals(3, ai.addAndGet(2));
168        assertEquals(3, ai.get());
169        assertEquals(-1, ai.addAndGet(-4));
170        assertEquals(-1, ai.get());
171    }
172
173    /**
174     * decrementAndGet decrements and returns current value
175     */
176    public void testDecrementAndGet() {
177        AtomicInteger ai = new AtomicInteger(1);
178        assertEquals(0, ai.decrementAndGet());
179        assertEquals(-1, ai.decrementAndGet());
180        assertEquals(-2, ai.decrementAndGet());
181        assertEquals(-2, ai.get());
182    }
183
184    /**
185     * incrementAndGet increments and returns current value
186     */
187    public void testIncrementAndGet() {
188        AtomicInteger ai = new AtomicInteger(1);
189        assertEquals(2, ai.incrementAndGet());
190        assertEquals(2, ai.get());
191        ai.set(-2);
192        assertEquals(-1, ai.incrementAndGet());
193        assertEquals(0, ai.incrementAndGet());
194        assertEquals(1, ai.incrementAndGet());
195        assertEquals(1, ai.get());
196    }
197
198    /**
199     * a deserialized serialized atomic holds same value
200     */
201    public void testSerialization() throws Exception {
202        AtomicInteger x = new AtomicInteger();
203        AtomicInteger y = serialClone(x);
204        assertNotSame(x, y);
205        x.set(22);
206        AtomicInteger z = serialClone(x);
207        assertEquals(22, x.get());
208        assertEquals(0, y.get());
209        assertEquals(22, z.get());
210    }
211
212    /**
213     * toString returns current value.
214     */
215    public void testToString() {
216        AtomicInteger ai = new AtomicInteger();
217        assertEquals("0", ai.toString());
218        for (int x : VALUES) {
219            ai.set(x);
220            assertEquals(Integer.toString(x), ai.toString());
221        }
222    }
223
224    /**
225     * intValue returns current value.
226     */
227    public void testIntValue() {
228        AtomicInteger ai = new AtomicInteger();
229        assertEquals(0, ai.intValue());
230        for (int x : VALUES) {
231            ai.set(x);
232            assertEquals(x, ai.intValue());
233        }
234    }
235
236    /**
237     * longValue returns current value.
238     */
239    public void testLongValue() {
240        AtomicInteger ai = new AtomicInteger();
241        assertEquals(0L, ai.longValue());
242        for (int x : VALUES) {
243            ai.set(x);
244            assertEquals((long)x, ai.longValue());
245        }
246    }
247
248    /**
249     * floatValue returns current value.
250     */
251    public void testFloatValue() {
252        AtomicInteger ai = new AtomicInteger();
253        assertEquals(0.0f, ai.floatValue());
254        for (int x : VALUES) {
255            ai.set(x);
256            assertEquals((float)x, ai.floatValue());
257        }
258    }
259
260    /**
261     * doubleValue returns current value.
262     */
263    public void testDoubleValue() {
264        AtomicInteger ai = new AtomicInteger();
265        assertEquals(0.0d, ai.doubleValue());
266        for (int x : VALUES) {
267            ai.set(x);
268            assertEquals((double)x, ai.doubleValue());
269        }
270    }
271
272}
273