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 5 package org.chromium.content.common; 6 7 import android.test.InstrumentationTestCase; 8 import android.test.suitebuilder.annotation.SmallTest; 9 10 import org.chromium.base.test.util.Feature; 11 import org.chromium.content.browser.test.util.Criteria; 12 import org.chromium.content.browser.test.util.CriteriaHelper; 13 14 import java.util.concurrent.atomic.AtomicInteger; 15 16 public 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 run()28 public void run() { 29 sObjectCount.decrementAndGet(); 30 } 31 }; 32 ReferredObject()33 public ReferredObject() { 34 sObjectCount.incrementAndGet(); 35 mRef = new CleanupReference(this, new DestroyRunnable()); 36 } 37 } 38 39 @Override setUp()40 public void setUp() throws Exception { 41 super.setUp(); 42 sObjectCount.set(0); 43 } 44 collectGarbage()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"}) testCreateSingle()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"}) testCreateMany()74 public void testCreateMany() throws Throwable { 75 assertEquals(0, sObjectCount.get()); 76 77 final int instanceCount = 20; 78 ReferredObject[] instances = new ReferredObject[instanceCount]; 79 80 for (int i = 0; i < instanceCount; ++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