Home | History | Annotate | Download | only in common
      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
     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 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