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
18package tests.api.java.lang.ref;
19
20import dalvik.annotation.TestTargets;
21import dalvik.annotation.TestLevel;
22import dalvik.annotation.TestTargetNew;
23import dalvik.annotation.TestTargetClass;
24
25import java.lang.ref.PhantomReference;
26import java.lang.ref.Reference;
27import java.lang.ref.ReferenceQueue;
28import java.lang.ref.SoftReference;
29import java.lang.ref.WeakReference;
30
31@TestTargetClass(ReferenceQueue.class)
32public class ReferenceQueueTest extends junit.framework.TestCase {
33    static Boolean b;
34
35    static Integer integer;
36    boolean isThrown = false;
37
38    protected void doneSuite() {
39        b = null;
40        integer = null;
41    }
42
43    public class ChildThread implements Runnable {
44        public ChildThread() {
45        }
46
47        public void run() {
48            try {
49                rq.wait(1000);
50            } catch (Exception e) {
51            }
52            synchronized (rq) {
53                // store in a static so it won't be gc'ed because the jit
54                // optimized it out
55                integer = new Integer(667);
56                SoftReference sr = new SoftReference(integer, rq);
57                sr.enqueue();
58                rq.notify();
59            }
60        }
61    }
62
63    ReferenceQueue rq;
64
65    /**
66     * @tests java.lang.ref.ReferenceQueue#poll()
67     */
68    @TestTargetNew(
69        level = TestLevel.COMPLETE,
70        notes = "",
71        method = "poll",
72        args = {}
73    )
74    public void test_poll() {
75        // store in a static so it won't be gc'ed because the jit
76        // optimized it out
77        b = new Boolean(true);
78        Object obj = new Object();
79        String str = "Test";
80
81        SoftReference sr = new SoftReference(b, rq);
82        WeakReference wr = new WeakReference(obj, rq);
83        PhantomReference pr = new PhantomReference(str, rq);
84        assertNull(rq.poll());
85        sr.enqueue();
86        wr.enqueue();
87        pr.enqueue();
88
89        try {
90            assertNull("Remove failed.", rq.poll().get());
91        } catch (Exception e) {
92            fail("Exception during the test : " + e.getMessage());
93        }
94
95        try {
96            assertEquals("Remove failed.", obj, (rq.poll().get()));
97        } catch (Exception e) {
98            fail("Exception during the test : " + e.getMessage());
99        }
100
101        try {
102            assertTrue("Remove failed.", ((Boolean) rq.poll().get())
103                    .booleanValue());
104        } catch (Exception e) {
105            fail("Exception during the test : " + e.getMessage());
106        }
107        assertNull(rq.poll());
108
109        sr.enqueue();
110        wr.enqueue();
111
112        System.gc();
113        System.runFinalization();
114
115        assertNull(rq.poll());
116    }
117
118    /**
119     * @tests java.lang.ref.ReferenceQueue#remove()
120     */
121    @TestTargetNew(
122        level = TestLevel.COMPLETE,
123        notes = "",
124        method = "remove",
125        args = {}
126    )
127    public void test_remove() {
128        // store in a static so it won't be gc'ed because the jit
129        // optimized it out
130        b = new Boolean(true);
131
132        SoftReference sr = new SoftReference(b, rq);
133        sr.enqueue();
134        try {
135            assertTrue("Remove failed.", ((Boolean) rq.remove().get())
136                    .booleanValue());
137        } catch (Exception e) {
138            fail("Exception during the test : " + e.getMessage());
139        }
140
141        assertNull(rq.poll());
142
143        sr.enqueue();
144
145        class RemoveThread extends Thread {
146            public void run() {
147                try {
148                    rq.remove();
149                } catch(InterruptedException ie) {
150                    isThrown = true;
151                }
152            }
153        }
154        RemoveThread rt = new RemoveThread();
155        rt.start();
156        try {
157            Thread.sleep(100);
158        } catch(InterruptedException ie) {
159
160        }
161        rt.interrupt();
162        try {
163            Thread.sleep(100);
164        } catch(InterruptedException ie) {
165
166        }
167        assertTrue(isThrown);
168        assertNull(rq.poll());
169    }
170
171    /**
172     * @tests java.lang.ref.ReferenceQueue#remove(long)
173     */
174    @TestTargetNew(
175        level = TestLevel.COMPLETE,
176        notes = "",
177        method = "remove",
178        args = {long.class}
179    )
180    public void test_removeJ() {
181        try {
182            assertNull("Queue should be empty. (poll)", rq.poll());
183            assertNull("Queue should be empty. (remove(1))",
184                    rq.remove((long) 1));
185            Thread ct = new Thread(new ChildThread());
186            ct.start();
187            Reference ret = rq.remove(0L);
188            assertNotNull("Delayed remove failed.", ret);
189        } catch (InterruptedException e) {
190            fail("InterruptedExeException during test : " + e.getMessage());
191        }
192        catch (Exception e) {
193            fail("Exception during test : " + e.getMessage());
194        }
195
196        Object obj = new Object();
197        WeakReference wr = new WeakReference(obj, rq);
198        Boolean b = new Boolean(true);
199        SoftReference sr = new SoftReference(b, rq);
200        String str = "Test";
201        PhantomReference pr = new PhantomReference(str, rq);
202
203        pr.enqueue();
204        wr.enqueue();
205        sr.enqueue();
206
207        try {
208            Reference result = rq.remove(1L);
209            assertTrue((Boolean)result.get());
210            result = rq.remove(1L);
211            assertEquals(obj, result.get());
212            result = rq.remove(1L);
213            assertNull(result.get());
214        } catch (IllegalArgumentException e1) {
215            fail("IllegalArgumentException was thrown.");
216        } catch (InterruptedException e1) {
217            fail("InterruptedException was thrown.");
218        }
219        rq = new ReferenceQueue();
220        isThrown = false;
221        assertNull(rq.poll());
222
223        class RemoveThread extends Thread {
224            public void run() {
225                try {
226                    rq.remove(1000L);
227                } catch(InterruptedException ie) {
228                    isThrown = true;
229                }
230            }
231        }
232        RemoveThread rt = new RemoveThread();
233        rt.start();
234        try {
235            Thread.sleep(10);
236        } catch(InterruptedException ie) {
237
238        }
239        rt.interrupt();
240        try {
241            Thread.sleep(10);
242        } catch(InterruptedException ie) {
243
244        }
245        assertTrue(isThrown);
246        assertNull(rq.poll());
247
248        try {
249            rq.remove(-1);
250            fail("IllegalArgumentException expected.");
251        } catch(IllegalArgumentException iae) {
252            //expected
253        } catch (InterruptedException e) {
254            fail("Unexpected InterruptedException.");
255        }
256    }
257
258    /**
259     * @tests java.lang.ref.ReferenceQueue#ReferenceQueue()
260     */
261    @TestTargetNew(
262        level = TestLevel.COMPLETE,
263        notes = "",
264        method = "ReferenceQueue",
265        args = {}
266    )
267    public void test_Constructor() {
268        ReferenceQueue rq = new ReferenceQueue();
269        assertNull(rq.poll());
270        try {
271            rq.remove(100L);
272        } catch (InterruptedException e) {
273            fail("InterruptedException was thrown.");
274        }
275    }
276
277    protected void setUp() {
278        rq = new ReferenceQueue();
279    }
280
281    protected void tearDown() {
282    }
283}
284