CleanupReferenceTest.java revision 3551c9c881056c480085172ff9840cab31610854
1// Copyright 2013 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5package org.chromium.content.common;
6
7import android.test.InstrumentationTestCase;
8import android.test.suitebuilder.annotation.SmallTest;
9
10import org.chromium.base.test.util.Feature;
11import org.chromium.content.browser.test.util.Criteria;
12import org.chromium.content.browser.test.util.CriteriaHelper;
13
14import java.util.concurrent.atomic.AtomicInteger;
15
16public class CleanupReferenceTest extends InstrumentationTestCase {
17
18    private static AtomicInteger sObjectCount = new AtomicInteger();
19
20    private static class ReferredObject {
21
22        private CleanupReference mRef;
23
24        // Remember: this MUST be a static class, to avoid an implicit ref back to the
25        // owning ReferredObject instance which would defeat GC of that object.
26        private static class DestroyRunnable implements Runnable {
27            @Override
28            public void run() {
29                sObjectCount.decrementAndGet();
30            }
31        };
32
33        public ReferredObject() {
34            sObjectCount.incrementAndGet();
35            mRef = new CleanupReference(this, new DestroyRunnable());
36        }
37    }
38
39    @Override
40    public void setUp() throws Exception {
41        super.setUp();
42        sObjectCount.set(0);
43    }
44
45    private void collectGarbage() {
46        // While this is only a 'hint' to the VM, it's generally effective and sufficient on
47        // dalvik. If this changes in future, maybe try allocating a few gargantuan objects
48        // too, to force the GC to work.
49        System.gc();
50    }
51
52    @SmallTest
53    @Feature({"AndroidWebView"})
54    public void testCreateSingle() throws Throwable {
55        assertEquals(0, sObjectCount.get());
56
57        ReferredObject instance = new ReferredObject();
58        assertEquals(1, sObjectCount.get());
59
60        instance = null;
61        // Ensure compiler / instrumentation does not strip out the assignment.
62        assertTrue(instance == null);
63        collectGarbage();
64        assertTrue(CriteriaHelper.pollForCriteria(new Criteria() {
65            @Override
66            public boolean isSatisfied() {
67                return sObjectCount.get() == 0;
68            }
69        }));
70    }
71
72    @SmallTest
73    @Feature({"AndroidWebView"})
74    public void testCreateMany() throws Throwable {
75        assertEquals(0, sObjectCount.get());
76
77        final int INSTANCE_COUNT = 20;
78        ReferredObject[] instances = new ReferredObject[INSTANCE_COUNT];
79
80        for (int i = 0; i < INSTANCE_COUNT; ++i) {
81            instances[i] = new ReferredObject();
82            assertEquals(i + 1, sObjectCount.get());
83        }
84
85        instances = null;
86        // Ensure compiler / instrumentation does not strip out the assignment.
87        assertTrue(instances == null);
88        collectGarbage();
89        assertTrue(CriteriaHelper.pollForCriteria(new Criteria() {
90            @Override
91            public boolean isSatisfied() {
92                return sObjectCount.get() == 0;
93            }
94        }));
95    }
96
97}
98