blob: 11bb398501deb7eccf9f5cf18489254d03064982 [file] [log] [blame]
Adrian Roose1e0b482017-02-02 16:00:59 -08001/*
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
17package com.android.systemui.util.leak;
18
19
20import android.support.test.filters.SmallTest;
21import android.support.test.runner.AndroidJUnit4;
22
Jason Monkfba8faf2017-05-23 10:42:59 -040023import com.android.systemui.SysuiTestCase;
Adrian Roose1e0b482017-02-02 16:00:59 -080024import com.android.systemui.util.leak.ReferenceTestUtils.CollectionWaiter;
25
26import org.junit.Before;
Andreas Gampe66745e92018-03-18 15:35:39 -070027import org.junit.Ignore;
Adrian Roose1e0b482017-02-02 16:00:59 -080028import org.junit.Test;
29import org.junit.runner.RunWith;
30
31import java.io.FileDescriptor;
32import java.io.FileNotFoundException;
33import java.io.FileOutputStream;
34import java.io.PrintWriter;
35import java.util.ArrayList;
36import java.util.Collection;
Søren Gjesse0fded552017-12-21 11:42:30 +010037import java.util.function.BiConsumer;
38import java.util.function.Consumer;
Adrian Roose1e0b482017-02-02 16:00:59 -080039
40@SmallTest
41@RunWith(AndroidJUnit4.class)
Jason Monkfba8faf2017-05-23 10:42:59 -040042public class LeakDetectorTest extends SysuiTestCase {
Adrian Roose1e0b482017-02-02 16:00:59 -080043
44 private LeakDetector mLeakDetector;
45
Søren Gjesse0fded552017-12-21 11:42:30 +010046 // The references for which collection is observed are stored in fields. The allocation and
47 // of these references happens in separate methods (trackObjectWith/trackCollectionWith)
48 // from where they are set to null. The generated code might keep the allocated reference
49 // alive in a dex register when compiling in release mode. As R8 is used to compile this
50 // test the --dontoptimize flag is also required to ensure that these methods are not
51 // inlined, as that would defeat the purpose of having the mutation in methods.
52 private Object mObject;
53 private Collection<?> mCollection;
54
55 private CollectionWaiter trackObjectWith(Consumer<Object> tracker) {
56 mObject = new Object();
57 CollectionWaiter collectionWaiter = ReferenceTestUtils.createCollectionWaiter(mObject);
58 tracker.accept(mObject);
59 return collectionWaiter;
60 }
61
62 private CollectionWaiter trackCollectionWith(
63 BiConsumer<? super Collection<?>, String> tracker) {
64 mCollection = new ArrayList<>();
65 CollectionWaiter collectionWaiter = ReferenceTestUtils.createCollectionWaiter(mCollection);
66 tracker.accept(mCollection, "tag");
67 return collectionWaiter;
68 }
69
Adrian Roose1e0b482017-02-02 16:00:59 -080070 @Before
71 public void setup() {
72 mLeakDetector = LeakDetector.create();
73
74 // Note: Do not try to factor out object / collection waiter creation. The optimizer will
75 // try and cache accesses to fields and thus create a GC root for the duration of the test
76 // method, thus breaking the test.
77 }
78
79 @Test
80 public void trackInstance_doesNotLeakTrackedObject() {
Søren Gjesse0fded552017-12-21 11:42:30 +010081 CollectionWaiter collectionWaiter = trackObjectWith(mLeakDetector::trackInstance);
82 mObject = null;
Adrian Roose1e0b482017-02-02 16:00:59 -080083 collectionWaiter.waitForCollection();
84 }
85
Andreas Gampe66745e92018-03-18 15:35:39 -070086 @Ignore("b/75329085")
Adrian Roose1e0b482017-02-02 16:00:59 -080087 @Test
88 public void trackCollection_doesNotLeakTrackedObject() {
Søren Gjesse0fded552017-12-21 11:42:30 +010089 CollectionWaiter collectionWaiter = trackCollectionWith(mLeakDetector::trackCollection);
90 mCollection = null;
Adrian Roose1e0b482017-02-02 16:00:59 -080091 collectionWaiter.waitForCollection();
92 }
93
94 @Test
95 public void trackGarbage_doesNotLeakTrackedObject() {
Søren Gjesse0fded552017-12-21 11:42:30 +010096 CollectionWaiter collectionWaiter = trackObjectWith(mLeakDetector::trackGarbage);
97 mObject = null;
Adrian Roose1e0b482017-02-02 16:00:59 -080098 collectionWaiter.waitForCollection();
99 }
100
101 @Test
102 public void testDump() throws Exception {
103 Object o1 = new Object();
104 Object o2 = new Object();
105 Collection<Object> col1 = new ArrayList<>();
106
107 mLeakDetector.trackInstance(o1);
108 mLeakDetector.trackCollection(col1, "tag");
109 mLeakDetector.trackGarbage(o2);
110
111 FileOutputStream fos = new FileOutputStream("/dev/null");
112 mLeakDetector.dump(fos.getFD(), new PrintWriter(fos), new String[0]);
113 }
114
115 @Test
116 public void testDisabled() throws Exception {
117 mLeakDetector = new LeakDetector(null, null, null);
118
119 Object o1 = new Object();
120 Object o2 = new Object();
121 Collection<Object> col1 = new ArrayList<>();
122
123 mLeakDetector.trackInstance(o1);
124 mLeakDetector.trackCollection(col1, "tag");
125 mLeakDetector.trackGarbage(o2);
126
127 FileOutputStream fos = new FileOutputStream("/dev/null");
128 mLeakDetector.dump(fos.getFD(), new PrintWriter(fos), new String[0]);
129 }
Søren Gjesse0fded552017-12-21 11:42:30 +0100130}