1e1e0b483be87d23383832aa6b558364a730c690fAdrian Roos/* 2e1e0b483be87d23383832aa6b558364a730c690fAdrian Roos * Copyright (C) 2017 The Android Open Source Project 3e1e0b483be87d23383832aa6b558364a730c690fAdrian Roos * 4e1e0b483be87d23383832aa6b558364a730c690fAdrian Roos * Licensed under the Apache License, Version 2.0 (the "License"); 5e1e0b483be87d23383832aa6b558364a730c690fAdrian Roos * you may not use this file except in compliance with the License. 6e1e0b483be87d23383832aa6b558364a730c690fAdrian Roos * You may obtain a copy of the License at 7e1e0b483be87d23383832aa6b558364a730c690fAdrian Roos * 8e1e0b483be87d23383832aa6b558364a730c690fAdrian Roos * http://www.apache.org/licenses/LICENSE-2.0 9e1e0b483be87d23383832aa6b558364a730c690fAdrian Roos * 10e1e0b483be87d23383832aa6b558364a730c690fAdrian Roos * Unless required by applicable law or agreed to in writing, software 11e1e0b483be87d23383832aa6b558364a730c690fAdrian Roos * distributed under the License is distributed on an "AS IS" BASIS, 12e1e0b483be87d23383832aa6b558364a730c690fAdrian Roos * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13e1e0b483be87d23383832aa6b558364a730c690fAdrian Roos * See the License for the specific language governing permissions and 14e1e0b483be87d23383832aa6b558364a730c690fAdrian Roos * limitations under the License 15e1e0b483be87d23383832aa6b558364a730c690fAdrian Roos */ 16e1e0b483be87d23383832aa6b558364a730c690fAdrian Roos 17e1e0b483be87d23383832aa6b558364a730c690fAdrian Roospackage com.android.systemui.util.leak; 18e1e0b483be87d23383832aa6b558364a730c690fAdrian Roos 19e1e0b483be87d23383832aa6b558364a730c690fAdrian Roos 20e1e0b483be87d23383832aa6b558364a730c690fAdrian Roosimport android.support.test.filters.SmallTest; 21e1e0b483be87d23383832aa6b558364a730c690fAdrian Roosimport android.support.test.runner.AndroidJUnit4; 22e1e0b483be87d23383832aa6b558364a730c690fAdrian Roos 23fba8faf5c5f58f115fa3c099da9ef0953b484147Jason Monkimport com.android.systemui.SysuiTestCase; 24e1e0b483be87d23383832aa6b558364a730c690fAdrian Roosimport com.android.systemui.util.leak.ReferenceTestUtils.CollectionWaiter; 25e1e0b483be87d23383832aa6b558364a730c690fAdrian Roos 26e1e0b483be87d23383832aa6b558364a730c690fAdrian Roosimport org.junit.Before; 27e1e0b483be87d23383832aa6b558364a730c690fAdrian Roosimport org.junit.Test; 28e1e0b483be87d23383832aa6b558364a730c690fAdrian Roosimport org.junit.runner.RunWith; 29e1e0b483be87d23383832aa6b558364a730c690fAdrian Roos 30e1e0b483be87d23383832aa6b558364a730c690fAdrian Roosimport java.io.FileDescriptor; 31e1e0b483be87d23383832aa6b558364a730c690fAdrian Roosimport java.io.FileNotFoundException; 32e1e0b483be87d23383832aa6b558364a730c690fAdrian Roosimport java.io.FileOutputStream; 33e1e0b483be87d23383832aa6b558364a730c690fAdrian Roosimport java.io.PrintWriter; 34e1e0b483be87d23383832aa6b558364a730c690fAdrian Roosimport java.util.ArrayList; 35e1e0b483be87d23383832aa6b558364a730c690fAdrian Roosimport java.util.Collection; 36e1e0b483be87d23383832aa6b558364a730c690fAdrian Roos 37e1e0b483be87d23383832aa6b558364a730c690fAdrian Roos@SmallTest 38e1e0b483be87d23383832aa6b558364a730c690fAdrian Roos@RunWith(AndroidJUnit4.class) 39fba8faf5c5f58f115fa3c099da9ef0953b484147Jason Monkpublic class LeakDetectorTest extends SysuiTestCase { 40e1e0b483be87d23383832aa6b558364a730c690fAdrian Roos 41e1e0b483be87d23383832aa6b558364a730c690fAdrian Roos private LeakDetector mLeakDetector; 42e1e0b483be87d23383832aa6b558364a730c690fAdrian Roos 43e1e0b483be87d23383832aa6b558364a730c690fAdrian Roos @Before 44e1e0b483be87d23383832aa6b558364a730c690fAdrian Roos public void setup() { 45e1e0b483be87d23383832aa6b558364a730c690fAdrian Roos mLeakDetector = LeakDetector.create(); 46e1e0b483be87d23383832aa6b558364a730c690fAdrian Roos 47e1e0b483be87d23383832aa6b558364a730c690fAdrian Roos // Note: Do not try to factor out object / collection waiter creation. The optimizer will 48e1e0b483be87d23383832aa6b558364a730c690fAdrian Roos // try and cache accesses to fields and thus create a GC root for the duration of the test 49e1e0b483be87d23383832aa6b558364a730c690fAdrian Roos // method, thus breaking the test. 50e1e0b483be87d23383832aa6b558364a730c690fAdrian Roos } 51e1e0b483be87d23383832aa6b558364a730c690fAdrian Roos 52e1e0b483be87d23383832aa6b558364a730c690fAdrian Roos @Test 53e1e0b483be87d23383832aa6b558364a730c690fAdrian Roos public void trackInstance_doesNotLeakTrackedObject() { 54e1e0b483be87d23383832aa6b558364a730c690fAdrian Roos Object object = new Object(); 55e1e0b483be87d23383832aa6b558364a730c690fAdrian Roos CollectionWaiter collectionWaiter = ReferenceTestUtils.createCollectionWaiter(object); 56e1e0b483be87d23383832aa6b558364a730c690fAdrian Roos 57e1e0b483be87d23383832aa6b558364a730c690fAdrian Roos mLeakDetector.trackInstance(object); 58e1e0b483be87d23383832aa6b558364a730c690fAdrian Roos object = null; 59e1e0b483be87d23383832aa6b558364a730c690fAdrian Roos collectionWaiter.waitForCollection(); 60e1e0b483be87d23383832aa6b558364a730c690fAdrian Roos } 61e1e0b483be87d23383832aa6b558364a730c690fAdrian Roos 62e1e0b483be87d23383832aa6b558364a730c690fAdrian Roos @Test 63e1e0b483be87d23383832aa6b558364a730c690fAdrian Roos public void trackCollection_doesNotLeakTrackedObject() { 64e1e0b483be87d23383832aa6b558364a730c690fAdrian Roos Collection<?> object = new ArrayList<>(); 65e1e0b483be87d23383832aa6b558364a730c690fAdrian Roos CollectionWaiter collectionWaiter = ReferenceTestUtils.createCollectionWaiter(object); 66e1e0b483be87d23383832aa6b558364a730c690fAdrian Roos 67e1e0b483be87d23383832aa6b558364a730c690fAdrian Roos mLeakDetector.trackCollection(object, "tag"); 68e1e0b483be87d23383832aa6b558364a730c690fAdrian Roos object = null; 69e1e0b483be87d23383832aa6b558364a730c690fAdrian Roos collectionWaiter.waitForCollection(); 70e1e0b483be87d23383832aa6b558364a730c690fAdrian Roos } 71e1e0b483be87d23383832aa6b558364a730c690fAdrian Roos 72e1e0b483be87d23383832aa6b558364a730c690fAdrian Roos @Test 73e1e0b483be87d23383832aa6b558364a730c690fAdrian Roos public void trackGarbage_doesNotLeakTrackedObject() { 74e1e0b483be87d23383832aa6b558364a730c690fAdrian Roos Object object = new Object(); 75e1e0b483be87d23383832aa6b558364a730c690fAdrian Roos CollectionWaiter collectionWaiter = ReferenceTestUtils.createCollectionWaiter(object); 76e1e0b483be87d23383832aa6b558364a730c690fAdrian Roos 77e1e0b483be87d23383832aa6b558364a730c690fAdrian Roos mLeakDetector.trackGarbage(object); 78e1e0b483be87d23383832aa6b558364a730c690fAdrian Roos object = null; 79e1e0b483be87d23383832aa6b558364a730c690fAdrian Roos collectionWaiter.waitForCollection(); 80e1e0b483be87d23383832aa6b558364a730c690fAdrian Roos } 81e1e0b483be87d23383832aa6b558364a730c690fAdrian Roos 82e1e0b483be87d23383832aa6b558364a730c690fAdrian Roos @Test 83e1e0b483be87d23383832aa6b558364a730c690fAdrian Roos public void testDump() throws Exception { 84e1e0b483be87d23383832aa6b558364a730c690fAdrian Roos Object o1 = new Object(); 85e1e0b483be87d23383832aa6b558364a730c690fAdrian Roos Object o2 = new Object(); 86e1e0b483be87d23383832aa6b558364a730c690fAdrian Roos Collection<Object> col1 = new ArrayList<>(); 87e1e0b483be87d23383832aa6b558364a730c690fAdrian Roos 88e1e0b483be87d23383832aa6b558364a730c690fAdrian Roos mLeakDetector.trackInstance(o1); 89e1e0b483be87d23383832aa6b558364a730c690fAdrian Roos mLeakDetector.trackCollection(col1, "tag"); 90e1e0b483be87d23383832aa6b558364a730c690fAdrian Roos mLeakDetector.trackGarbage(o2); 91e1e0b483be87d23383832aa6b558364a730c690fAdrian Roos 92e1e0b483be87d23383832aa6b558364a730c690fAdrian Roos FileOutputStream fos = new FileOutputStream("/dev/null"); 93e1e0b483be87d23383832aa6b558364a730c690fAdrian Roos mLeakDetector.dump(fos.getFD(), new PrintWriter(fos), new String[0]); 94e1e0b483be87d23383832aa6b558364a730c690fAdrian Roos } 95e1e0b483be87d23383832aa6b558364a730c690fAdrian Roos 96e1e0b483be87d23383832aa6b558364a730c690fAdrian Roos @Test 97e1e0b483be87d23383832aa6b558364a730c690fAdrian Roos public void testDisabled() throws Exception { 98e1e0b483be87d23383832aa6b558364a730c690fAdrian Roos mLeakDetector = new LeakDetector(null, null, null); 99e1e0b483be87d23383832aa6b558364a730c690fAdrian Roos 100e1e0b483be87d23383832aa6b558364a730c690fAdrian Roos Object o1 = new Object(); 101e1e0b483be87d23383832aa6b558364a730c690fAdrian Roos Object o2 = new Object(); 102e1e0b483be87d23383832aa6b558364a730c690fAdrian Roos Collection<Object> col1 = new ArrayList<>(); 103e1e0b483be87d23383832aa6b558364a730c690fAdrian Roos 104e1e0b483be87d23383832aa6b558364a730c690fAdrian Roos mLeakDetector.trackInstance(o1); 105e1e0b483be87d23383832aa6b558364a730c690fAdrian Roos mLeakDetector.trackCollection(col1, "tag"); 106e1e0b483be87d23383832aa6b558364a730c690fAdrian Roos mLeakDetector.trackGarbage(o2); 107e1e0b483be87d23383832aa6b558364a730c690fAdrian Roos 108e1e0b483be87d23383832aa6b558364a730c690fAdrian Roos FileOutputStream fos = new FileOutputStream("/dev/null"); 109e1e0b483be87d23383832aa6b558364a730c690fAdrian Roos mLeakDetector.dump(fos.getFD(), new PrintWriter(fos), new String[0]); 110e1e0b483be87d23383832aa6b558364a730c690fAdrian Roos } 111e1e0b483be87d23383832aa6b558364a730c690fAdrian Roos}