• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2019 The Chromium Authors
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.base;
6 
7 import org.junit.After;
8 import org.junit.Assert;
9 import org.junit.Before;
10 import org.junit.Test;
11 import org.junit.runner.RunWith;
12 import org.robolectric.annotation.Config;
13 
14 import org.chromium.base.test.BaseRobolectricTestRunner;
15 import org.chromium.build.BuildConfig;
16 
17 /** junit tests for {@link LifetimeAssert}. */
18 @RunWith(BaseRobolectricTestRunner.class)
19 @Config(manifest = Config.NONE)
20 public class LifetimeAssertTest {
21     private static class TestClass {
22         // Put assert inside of a test class to mirror typical api usage.
23         final LifetimeAssert mLifetimeAssert = LifetimeAssert.create(this);
24     }
25 
26     private final Object mLock = new Object();
27     private TestClass mTestClass;
28     private LifetimeAssert.WrappedReference mTargetRef;
29     private boolean mFound;
30     private String mHookMessage;
31 
32     @Before
setUp()33     public void setUp() {
34         if (!BuildConfig.ENABLE_ASSERTS) {
35             return;
36         }
37         mTestClass = new TestClass();
38         mTargetRef = mTestClass.mLifetimeAssert.mWrapper;
39         mFound = false;
40         mHookMessage = null;
41         LifetimeAssert.sTestHook =
42                 (ref, msg) -> {
43                     if (ref == mTargetRef) {
44                         synchronized (mLock) {
45                             mFound = true;
46                             mHookMessage = msg;
47                             mLock.notify();
48                         }
49                     }
50                 };
51     }
52 
53     @After
tearDown()54     public void tearDown() {
55         if (!BuildConfig.ENABLE_ASSERTS) {
56             return;
57         }
58         LifetimeAssert.sTestHook = null;
59     }
60 
runTest(boolean setSafe)61     private void runTest(boolean setSafe) {
62         if (!BuildConfig.ENABLE_ASSERTS) {
63             return;
64         }
65 
66         synchronized (mLock) {
67             if (setSafe) {
68                 LifetimeAssert.setSafeToGc(mTestClass.mLifetimeAssert, true);
69             }
70             // Null out field to make reference GC'able.
71             mTestClass = null;
72             // Call System.gc() until the background thread notices the reference.
73             for (int i = 0; i < 10 && !mFound; ++i) {
74                 System.gc();
75                 try {
76                     mLock.wait(200);
77                 } catch (InterruptedException e) {
78                 }
79             }
80             Assert.assertTrue(mFound);
81             if (setSafe) {
82                 Assert.assertNull(mHookMessage);
83             } else {
84                 Assert.assertNotNull(mHookMessage);
85             }
86         }
87     }
88 
89     @Test
testSafeGc()90     public void testSafeGc() {
91         runTest(true);
92     }
93 
94     @Test
testUnsafeGc()95     public void testUnsafeGc() {
96         runTest(false);
97     }
98 
99     @Test
testAssertAllInstancesDestroyedForTesting_notSafeToGc()100     public void testAssertAllInstancesDestroyedForTesting_notSafeToGc() {
101         if (!BuildConfig.ENABLE_ASSERTS) {
102             return;
103         }
104         try {
105             LifetimeAssert.assertAllInstancesDestroyedForTesting();
106             Assert.fail();
107         } catch (LifetimeAssert.LifetimeAssertException e) {
108             // Expected.
109         }
110     }
111 
112     @Test
testAssertAllInstancesDestroyedForTesting_safeToGc()113     public void testAssertAllInstancesDestroyedForTesting_safeToGc() {
114         if (!BuildConfig.ENABLE_ASSERTS) {
115             return;
116         }
117         LifetimeAssert.setSafeToGc(mTestClass.mLifetimeAssert, true);
118         // Should not throw.
119         LifetimeAssert.assertAllInstancesDestroyedForTesting();
120     }
121 
122     @Test
testAssertAllInstancesDestroyedForTesting_resetAfterAssert()123     public void testAssertAllInstancesDestroyedForTesting_resetAfterAssert() {
124         if (!BuildConfig.ENABLE_ASSERTS) {
125             return;
126         }
127         try {
128             LifetimeAssert.assertAllInstancesDestroyedForTesting();
129             Assert.fail();
130         } catch (LifetimeAssert.LifetimeAssertException e) {
131             // Expected.
132         }
133         // Should no longer throw.
134         LifetimeAssert.assertAllInstancesDestroyedForTesting();
135     }
136 
137     @Test
testResetForTesting()138     public void testResetForTesting() {
139         if (!BuildConfig.ENABLE_ASSERTS) {
140             return;
141         }
142         LifetimeAssert.resetForTesting();
143         // Should not throw.
144         LifetimeAssert.assertAllInstancesDestroyedForTesting();
145     }
146 }
147