1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package com.google.common.testing;
18
19 import com.google.common.testing.GcFinalization.FinalizationPredicate;
20 import com.google.common.util.concurrent.SettableFuture;
21
22 import junit.framework.TestCase;
23
24 import java.lang.ref.WeakReference;
25 import java.util.WeakHashMap;
26 import java.util.concurrent.CountDownLatch;
27 import java.util.concurrent.atomic.AtomicBoolean;
28
29
30
31
32
33
34
35
36 public class GcFinalizationTest extends TestCase {
37
38
39
40
41
42 public void testAwait_CountDownLatch() {
43 final CountDownLatch latch = new CountDownLatch(1);
44 Object x = new Object() {
45 @Override protected void finalize() { latch.countDown(); }
46 };
47 x = null;
48 GcFinalization.await(latch);
49 assertEquals(0, latch.getCount());
50 }
51
52 public void testAwaitDone_Future() {
53 final SettableFuture<Void> future = SettableFuture.create();
54 Object x = new Object() {
55 @Override protected void finalize() { future.set(null); }
56 };
57 x = null;
58 GcFinalization.awaitDone(future);
59 assertTrue(future.isDone());
60 assertFalse(future.isCancelled());
61 }
62
63 public void testAwaitDone_Future_Cancel() {
64 final SettableFuture<Void> future = SettableFuture.create();
65 Object x = new Object() {
66 @Override protected void finalize() { future.cancel(false); }
67 };
68 x = null;
69 GcFinalization.awaitDone(future);
70 assertTrue(future.isDone());
71 assertTrue(future.isCancelled());
72 }
73
74 public void testAwaitClear() {
75 final WeakReference<Object> ref = new WeakReference<Object>(new Object());
76 GcFinalization.awaitClear(ref);
77 assertNull(ref.get());
78 }
79
80 public void testAwaitDone_FinalizationPredicate() {
81 final WeakHashMap<Object, Object> map = new WeakHashMap<Object, Object>();
82 map.put(new Object(), Boolean.TRUE);
83 GcFinalization.awaitDone(new FinalizationPredicate() {
84 public boolean isDone() {
85 return map.isEmpty();
86 }
87 });
88 assertTrue(map.isEmpty());
89 }
90
91
92
93
94
95
96 class Interruptenator extends Thread {
97 final AtomicBoolean shutdown;
98 Interruptenator(final Thread interruptee) {
99 this(interruptee, new AtomicBoolean(false));
100 }
101 Interruptenator(final Thread interruptee,
102 final AtomicBoolean shutdown) {
103 super(new Runnable() {
104 public void run() {
105 while (!shutdown.get()) {
106 interruptee.interrupt();
107 Thread.yield();
108 }}});
109 this.shutdown = shutdown;
110 start();
111 }
112 void shutdown() {
113 shutdown.set(true);
114 while (this.isAlive()) {
115 Thread.yield();
116 }
117 }
118 }
119
120 void assertWrapsInterruptedException(RuntimeException e) {
121 assertTrue(e.getMessage().contains("Unexpected interrupt"));
122 assertTrue(e.getCause() instanceof InterruptedException);
123 }
124
125 public void testAwait_CountDownLatch_Interrupted() {
126 Interruptenator interruptenator = new Interruptenator(Thread.currentThread());
127 try {
128 final CountDownLatch latch = new CountDownLatch(1);
129 try {
130 GcFinalization.await(latch);
131 fail("should throw");
132 } catch (RuntimeException expected) {
133 assertWrapsInterruptedException(expected);
134 }
135 } finally {
136 interruptenator.shutdown();
137 Thread.interrupted();
138 }
139 }
140
141 public void testAwaitDone_Future_Interrupted_Interrupted() {
142 Interruptenator interruptenator = new Interruptenator(Thread.currentThread());
143 try {
144 final SettableFuture<Void> future = SettableFuture.create();
145 try {
146 GcFinalization.awaitDone(future);
147 fail("should throw");
148 } catch (RuntimeException expected) {
149 assertWrapsInterruptedException(expected);
150 }
151 } finally {
152 interruptenator.shutdown();
153 Thread.interrupted();
154 }
155 }
156
157 public void testAwaitClear_Interrupted() {
158 Interruptenator interruptenator = new Interruptenator(Thread.currentThread());
159 try {
160 final WeakReference<Object> ref = new WeakReference<Object>(Boolean.TRUE);
161 try {
162 GcFinalization.awaitClear(ref);
163 fail("should throw");
164 } catch (RuntimeException expected) {
165 assertWrapsInterruptedException(expected);
166 }
167 } finally {
168 interruptenator.shutdown();
169 Thread.interrupted();
170 }
171 }
172
173 public void testAwaitDone_FinalizationPredicate_Interrupted() {
174 Interruptenator interruptenator = new Interruptenator(Thread.currentThread());
175 try {
176 try {
177 GcFinalization.awaitDone(new FinalizationPredicate() {
178 public boolean isDone() {
179 return false;
180 }
181 });
182 fail("should throw");
183 } catch (RuntimeException expected) {
184 assertWrapsInterruptedException(expected);
185 }
186 } finally {
187 interruptenator.shutdown();
188 Thread.interrupted();
189 }
190 }
191
192
193
194
195
196
197
198 public void testAwaitFullGc() {
199 final CountDownLatch finalizerRan = new CountDownLatch(1);
200 final WeakReference<Object> ref = new WeakReference<Object>(
201 new Object() {
202 @Override protected void finalize() { finalizerRan.countDown(); }
203 });
204
205
206
207 GcFinalization.awaitFullGc();
208
209
210
211
212 assertEquals(0, finalizerRan.getCount());
213 assertNull(ref.get());
214 }
215
216 }