1/* 2 * Copyright (C) 2016 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 */ 16package dalvik.system; 17 18import org.junit.Rule; 19import org.junit.Test; 20import org.junit.rules.TestRule; 21import org.junit.runner.Description; 22import org.junit.runners.model.Statement; 23 24/** 25 * Tests {@link CloseGuard}. 26 */ 27public class CloseGuardTest { 28 29 /** 30 * Resets the {@link CloseGuard#ENABLED} state back to the value it had when the test started. 31 */ 32 @Rule 33 public TestRule rule = this::preserveEnabledState; 34 35 private Statement preserveEnabledState(final Statement base, Description description) { 36 return new Statement() { 37 @Override 38 public void evaluate() throws Throwable { 39 boolean oldEnabledState = CloseGuard.isEnabled(); 40 try { 41 base.evaluate(); 42 } finally { 43 CloseGuard.setEnabled(oldEnabledState); 44 } 45 } 46 }; 47 } 48 49 @Test 50 public void testEnabled_NotOpen() throws Throwable { 51 CloseGuard.setEnabled(true); 52 ResourceOwner owner = new ResourceOwner(); 53 assertUnreleasedResources(owner, 0); 54 } 55 56 @Test 57 public void testEnabled_OpenNotClosed() throws Throwable { 58 CloseGuard.setEnabled(true); 59 ResourceOwner owner = new ResourceOwner(); 60 owner.open(); 61 assertUnreleasedResources(owner, 1); 62 } 63 64 @Test 65 public void testEnabled_OpenThenClosed() throws Throwable { 66 CloseGuard.setEnabled(true); 67 ResourceOwner owner = new ResourceOwner(); 68 owner.open(); 69 owner.close(); 70 assertUnreleasedResources(owner, 0); 71 } 72 73 @Test 74 public void testEnabledWhenCreated_DisabledWhenOpen() throws Throwable { 75 CloseGuard.setEnabled(true); 76 ResourceOwner owner = new ResourceOwner(); 77 CloseGuard.setEnabled(false); 78 owner.open(); 79 80 // Although the resource was not released it should not report it because CloseGuard was 81 // not enabled when the CloseGuard was opened. 82 assertUnreleasedResources(owner, 0); 83 } 84 85 @Test 86 public void testEnabledWhenOpened_DisabledWhenFinalized() throws Throwable { 87 CloseGuard.setEnabled(true); 88 ResourceOwner owner = new ResourceOwner(); 89 owner.open(); 90 CloseGuard.setEnabled(false); 91 92 // Although the resource was not released it should not report it because CloseGuard was 93 // not enabled when the CloseGuard was finalized. 94 assertUnreleasedResources(owner, 0); 95 } 96 97 @Test 98 public void testDisabled_NotOpen() throws Throwable { 99 CloseGuard.setEnabled(false); 100 ResourceOwner owner = new ResourceOwner(); 101 assertUnreleasedResources(owner, 0); 102 } 103 104 @Test 105 public void testDisabled_OpenNotClosed() throws Throwable { 106 CloseGuard.setEnabled(false); 107 ResourceOwner owner = new ResourceOwner(); 108 owner.open(); 109 assertUnreleasedResources(owner, 0); 110 } 111 112 @Test 113 public void testDisabled_OpenThenClosed() throws Throwable { 114 CloseGuard.setEnabled(false); 115 ResourceOwner owner = new ResourceOwner(); 116 owner.open(); 117 owner.close(); 118 assertUnreleasedResources(owner, 0); 119 } 120 121 @Test 122 public void testDisabledWhenCreated_EnabledWhenOpen() throws Throwable { 123 CloseGuard.setEnabled(false); 124 ResourceOwner owner = new ResourceOwner(); 125 CloseGuard.setEnabled(true); 126 owner.open(); 127 128 // Although the resource was not released it should not report it because CloseGuard was 129 // not enabled when the CloseGuard was created. 130 assertUnreleasedResources(owner, 0); 131 } 132 133 private void assertUnreleasedResources(ResourceOwner owner, int expectedCount) 134 throws Throwable { 135 try { 136 CloseGuardSupport.getFinalizerChecker().accept(owner, expectedCount); 137 } finally { 138 // Close the resource so that CloseGuard does not generate a warning for real when it 139 // is actually finalized. 140 owner.close(); 141 } 142 } 143 144 /** 145 * A test user of {@link CloseGuard}. 146 */ 147 private static class ResourceOwner { 148 149 private final CloseGuard closeGuard; 150 151 ResourceOwner() { 152 closeGuard = CloseGuard.get(); 153 } 154 155 public void open() { 156 closeGuard.open("close"); 157 } 158 159 public void close() { 160 closeGuard.close(); 161 } 162 163 /** 164 * Make finalize public so that it can be tested directly without relying on garbage 165 * collection to trigger it. 166 */ 167 @Override 168 public void finalize() throws Throwable { 169 closeGuard.warnIfOpen(); 170 super.finalize(); 171 } 172 } 173} 174