1fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin/* 2fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin * Copyright (C) 2016 The Android Open Source Project 3fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin * 4fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin * Licensed under the Apache License, Version 2.0 (the "License"); 5fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin * you may not use this file except in compliance with the License. 6fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin * You may obtain a copy of the License at 7fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin * 8fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin * http://www.apache.org/licenses/LICENSE-2.0 9fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin * 10fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin * Unless required by applicable law or agreed to in writing, software 11fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin * distributed under the License is distributed on an "AS IS" BASIS, 12fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin * See the License for the specific language governing permissions and 14fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin * limitations under the License. 15fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin */ 16fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffinpackage dalvik.system; 17fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin 18fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffinimport org.junit.Rule; 19fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffinimport org.junit.Test; 20fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffinimport org.junit.rules.TestRule; 21fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffinimport org.junit.runner.Description; 22fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffinimport org.junit.runners.model.Statement; 23fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin 24fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin/** 25fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin * Tests {@link CloseGuard}. 26fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin */ 27fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffinpublic class CloseGuardTest { 28fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin 29fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin /** 30fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin * Resets the {@link CloseGuard#ENABLED} state back to the value it had when the test started. 31fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin */ 32fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin @Rule 33fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin public TestRule rule = this::preserveEnabledState; 34fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin 35fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin private Statement preserveEnabledState(final Statement base, Description description) { 36fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin return new Statement() { 37fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin @Override 38fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin public void evaluate() throws Throwable { 39fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin boolean oldEnabledState = CloseGuard.isEnabled(); 40fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin try { 41fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin base.evaluate(); 42fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin } finally { 43fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin CloseGuard.setEnabled(oldEnabledState); 44fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin } 45fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin } 46fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin }; 47fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin } 48fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin 49fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin @Test 50fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin public void testEnabled_NotOpen() throws Throwable { 51fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin CloseGuard.setEnabled(true); 52fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin ResourceOwner owner = new ResourceOwner(); 53fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin assertUnreleasedResources(owner, 0); 54fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin } 55fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin 56fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin @Test 57fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin public void testEnabled_OpenNotClosed() throws Throwable { 58fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin CloseGuard.setEnabled(true); 59fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin ResourceOwner owner = new ResourceOwner(); 60fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin owner.open(); 61fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin assertUnreleasedResources(owner, 1); 62fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin } 63fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin 64fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin @Test 65fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin public void testEnabled_OpenThenClosed() throws Throwable { 66fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin CloseGuard.setEnabled(true); 67fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin ResourceOwner owner = new ResourceOwner(); 68fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin owner.open(); 69fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin owner.close(); 70fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin assertUnreleasedResources(owner, 0); 71fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin } 72fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin 73fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin @Test 74fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin public void testEnabledWhenCreated_DisabledWhenOpen() throws Throwable { 75fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin CloseGuard.setEnabled(true); 76fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin ResourceOwner owner = new ResourceOwner(); 77fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin CloseGuard.setEnabled(false); 78fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin owner.open(); 79fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin 80fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin // Although the resource was not released it should not report it because CloseGuard was 81fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin // not enabled when the CloseGuard was opened. 82fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin assertUnreleasedResources(owner, 0); 83fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin } 84fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin 85fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin @Test 86fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin public void testEnabledWhenOpened_DisabledWhenFinalized() throws Throwable { 87fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin CloseGuard.setEnabled(true); 88fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin ResourceOwner owner = new ResourceOwner(); 89fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin owner.open(); 90fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin CloseGuard.setEnabled(false); 91fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin 92fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin // Although the resource was not released it should not report it because CloseGuard was 93fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin // not enabled when the CloseGuard was finalized. 94fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin assertUnreleasedResources(owner, 0); 95fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin } 96fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin 97fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin @Test 98fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin public void testDisabled_NotOpen() throws Throwable { 99fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin CloseGuard.setEnabled(false); 100fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin ResourceOwner owner = new ResourceOwner(); 101fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin assertUnreleasedResources(owner, 0); 102fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin } 103fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin 104fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin @Test 105fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin public void testDisabled_OpenNotClosed() throws Throwable { 106fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin CloseGuard.setEnabled(false); 107fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin ResourceOwner owner = new ResourceOwner(); 108fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin owner.open(); 109fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin assertUnreleasedResources(owner, 0); 110fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin } 111fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin 112fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin @Test 113fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin public void testDisabled_OpenThenClosed() throws Throwable { 114fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin CloseGuard.setEnabled(false); 115fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin ResourceOwner owner = new ResourceOwner(); 116fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin owner.open(); 117fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin owner.close(); 118fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin assertUnreleasedResources(owner, 0); 119fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin } 120fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin 121fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin @Test 122fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin public void testDisabledWhenCreated_EnabledWhenOpen() throws Throwable { 123fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin CloseGuard.setEnabled(false); 124fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin ResourceOwner owner = new ResourceOwner(); 125fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin CloseGuard.setEnabled(true); 126fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin owner.open(); 127fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin 128fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin // Although the resource was not released it should not report it because CloseGuard was 129fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin // not enabled when the CloseGuard was created. 130fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin assertUnreleasedResources(owner, 0); 131fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin } 132fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin 133fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin private void assertUnreleasedResources(ResourceOwner owner, int expectedCount) 134fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin throws Throwable { 135fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin try { 136fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin CloseGuardSupport.getFinalizerChecker().accept(owner, expectedCount); 137fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin } finally { 138fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin // Close the resource so that CloseGuard does not generate a warning for real when it 139fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin // is actually finalized. 140fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin owner.close(); 141fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin } 142fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin } 143fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin 144fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin /** 145fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin * A test user of {@link CloseGuard}. 146fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin */ 147fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin private static class ResourceOwner { 148fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin 149fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin private final CloseGuard closeGuard; 150fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin 151fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin ResourceOwner() { 152fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin closeGuard = CloseGuard.get(); 153fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin } 154fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin 155fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin public void open() { 156fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin closeGuard.open("close"); 157fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin } 158fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin 159fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin public void close() { 160fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin closeGuard.close(); 161fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin } 162fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin 163fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin /** 164fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin * Make finalize public so that it can be tested directly without relying on garbage 165fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin * collection to trigger it. 166fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin */ 167fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin @Override 168fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin public void finalize() throws Throwable { 169fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin closeGuard.warnIfOpen(); 170fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin super.finalize(); 171fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin } 172fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin } 173fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin} 174