1 /* 2 * Copyright (C) 2017 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License 15 */ 16 17 package com.android.systemui.util.leak; 18 19 import static org.mockito.ArgumentMatchers.anyInt; 20 import static org.mockito.Mockito.mock; 21 import static org.mockito.Mockito.never; 22 import static org.mockito.Mockito.verify; 23 import static org.mockito.Mockito.when; 24 25 import android.content.Context; 26 import android.os.Looper; 27 import android.support.test.filters.SmallTest; 28 import android.testing.AndroidTestingRunner; 29 import android.testing.TestableLooper; 30 import android.testing.TestableLooper.RunWithLooper; 31 32 import com.android.systemui.SysuiTestCase; 33 34 import org.junit.Before; 35 import org.junit.Test; 36 import org.junit.runner.RunWith; 37 38 @SmallTest 39 @RunWith(AndroidTestingRunner.class) 40 @RunWithLooper 41 public class GarbageMonitorTest extends SysuiTestCase { 42 43 private LeakReporter mLeakReporter; 44 private TrackedGarbage mTrackedGarbage; 45 private TestableGarbageMonitor mGarbageMonitor; 46 47 @Before 48 public void setup() { 49 mTrackedGarbage = mock(TrackedGarbage.class); 50 mLeakReporter = mock(LeakReporter.class); 51 mGarbageMonitor = 52 new TestableGarbageMonitor( 53 mContext, 54 TestableLooper.get(this).getLooper(), 55 new LeakDetector(null, mTrackedGarbage, null), 56 mLeakReporter); 57 } 58 59 @Test 60 public void testCallbacks_getScheduled() { 61 mGarbageMonitor.startLeakMonitor(); 62 mGarbageMonitor.runCallbacksOnce(); 63 mGarbageMonitor.runCallbacksOnce(); 64 mGarbageMonitor.runCallbacksOnce(); 65 } 66 67 @Test 68 public void testNoGarbage_doesntDump() { 69 when(mTrackedGarbage.countOldGarbage()).thenReturn(0); 70 71 mGarbageMonitor.startLeakMonitor(); 72 mGarbageMonitor.runCallbacksOnce(); 73 mGarbageMonitor.runCallbacksOnce(); 74 mGarbageMonitor.runCallbacksOnce(); 75 76 verify(mLeakReporter, never()).dumpLeak(anyInt()); 77 } 78 79 @Test 80 public void testALittleGarbage_doesntDump() { 81 when(mTrackedGarbage.countOldGarbage()).thenReturn(4); 82 83 mGarbageMonitor.startLeakMonitor(); 84 mGarbageMonitor.runCallbacksOnce(); 85 mGarbageMonitor.runCallbacksOnce(); 86 mGarbageMonitor.runCallbacksOnce(); 87 88 verify(mLeakReporter, never()).dumpLeak(anyInt()); 89 } 90 91 @Test 92 public void testTransientGarbage_doesntDump() { 93 when(mTrackedGarbage.countOldGarbage()).thenReturn(100); 94 95 mGarbageMonitor.startLeakMonitor(); 96 mGarbageMonitor.runInspectCallback(); 97 98 when(mTrackedGarbage.countOldGarbage()).thenReturn(0); 99 100 mGarbageMonitor.runReinspectCallback(); 101 102 verify(mLeakReporter, never()).dumpLeak(anyInt()); 103 } 104 105 @Test 106 public void testLotsOfPersistentGarbage_dumps() { 107 when(mTrackedGarbage.countOldGarbage()).thenReturn(100); 108 109 mGarbageMonitor.startLeakMonitor(); 110 mGarbageMonitor.runCallbacksOnce(); 111 112 verify(mLeakReporter).dumpLeak(anyInt()); 113 } 114 115 private static class TestableGarbageMonitor extends GarbageMonitor { 116 public TestableGarbageMonitor( 117 Context context, 118 Looper looper, 119 LeakDetector leakDetector, 120 LeakReporter leakReporter) { 121 super(context, looper, leakDetector, leakReporter); 122 } 123 124 void runInspectCallback() { 125 startLeakMonitor(); 126 } 127 128 void runReinspectCallback() { 129 reinspectGarbageAfterGc(); 130 } 131 132 void runCallbacksOnce() { 133 // Note that TestableLooper doesn't currently support delayed messages so we need to run 134 // callbacks explicitly. 135 runInspectCallback(); 136 runReinspectCallback(); 137 } 138 } 139 }