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 libcore.junit.util; 17fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin 1827604018f783bf6354a13870b3e7785edca69b5fPaul Duffinimport java.lang.annotation.ElementType; 1927604018f783bf6354a13870b3e7785edca69b5fPaul Duffinimport java.lang.annotation.Retention; 2027604018f783bf6354a13870b3e7785edca69b5fPaul Duffinimport java.lang.annotation.RetentionPolicy; 2127604018f783bf6354a13870b3e7785edca69b5fPaul Duffinimport java.lang.annotation.Target; 22fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffinimport java.lang.reflect.Method; 23fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffinimport java.util.function.BiConsumer; 24fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffinimport org.junit.rules.RuleChain; 25fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffinimport org.junit.rules.TestRule; 26fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffinimport org.junit.runner.Description; 27fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffinimport org.junit.runners.model.Statement; 28fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin 29fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin/** 3088df7911980a895f9379d9a0e4cbf46aaadf90d0Paul Duffin * Provides support for testing classes that own resources (using {@code CloseGuard} mechanism) 3188df7911980a895f9379d9a0e4cbf46aaadf90d0Paul Duffin * which must not leak. 32fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin * 33fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin * <p><strong>This will not detect any resource leakages in OpenJDK</strong></p> 3488df7911980a895f9379d9a0e4cbf46aaadf90d0Paul Duffin * 3588df7911980a895f9379d9a0e4cbf46aaadf90d0Paul Duffin * <p>Typical usage for developers that want to ensure that their tests do not leak resources: 3688df7911980a895f9379d9a0e4cbf46aaadf90d0Paul Duffin * <pre> 3788df7911980a895f9379d9a0e4cbf46aaadf90d0Paul Duffin * public class ResourceTest { 3888df7911980a895f9379d9a0e4cbf46aaadf90d0Paul Duffin * {@code @Rule} 3988df7911980a895f9379d9a0e4cbf46aaadf90d0Paul Duffin * public LeakageDetectorRule leakageDetectorRule = ResourceLeakageDetector.getRule(); 4088df7911980a895f9379d9a0e4cbf46aaadf90d0Paul Duffin * 4188df7911980a895f9379d9a0e4cbf46aaadf90d0Paul Duffin * ... 4288df7911980a895f9379d9a0e4cbf46aaadf90d0Paul Duffin * } 4388df7911980a895f9379d9a0e4cbf46aaadf90d0Paul Duffin * </pre> 4488df7911980a895f9379d9a0e4cbf46aaadf90d0Paul Duffin * 4588df7911980a895f9379d9a0e4cbf46aaadf90d0Paul Duffin * <p>Developers that need to test the resource itself to ensure it is properly protected can 4688df7911980a895f9379d9a0e4cbf46aaadf90d0Paul Duffin * use {@link LeakageDetectorRule#assertUnreleasedResourceCount(Object, int) 4788df7911980a895f9379d9a0e4cbf46aaadf90d0Paul Duffin * assertUnreleasedResourceCount(Object, int)}. 48fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin */ 49fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffinpublic class ResourceLeakageDetector { 50fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin private static final LeakageDetectorRule LEAKAGE_DETECTOR_RULE; 51fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin private static final BiConsumer<Object, Integer> FINALIZER_CHECKER; 52fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin 53fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin static { 54fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin LeakageDetectorRule leakageDetectorRule; 55fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin BiConsumer<Object, Integer> finalizerChecker; 56fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin try { 57fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin // Make sure that the CloseGuard class exists; this ensures that this is not 58fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin // running on a RI JVM. 59fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin Class.forName("dalvik.system.CloseGuard"); 60fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin 61fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin // Access the underlying support class using reflection in order to prevent any compile 62fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin // time dependencies on it so as to allow this to compile on OpenJDK. 63fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin Class<?> closeGuardSupportClass = Class.forName("dalvik.system.CloseGuardSupport"); 64fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin Method method = closeGuardSupportClass.getMethod("getRule"); 65fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin leakageDetectorRule = new LeakageDetectorRule((TestRule) method.invoke(null)); 66fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin 67fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin finalizerChecker = getFinalizerChecker(closeGuardSupportClass); 68fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin 69fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin } catch (ReflectiveOperationException e) { 70fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin System.err.println("Resource leakage will not be detected; " 71fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin + "this is expected in the reference implementation"); 72fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin e.printStackTrace(System.err); 73fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin 74fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin // Could not access the class for some reason so have a rule that does nothing and a 75fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin // finalizer checker that checks nothing. This should ensure that tests work properly 76fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin // on OpenJDK even though it does not support CloseGuard. 77fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin leakageDetectorRule = new LeakageDetectorRule(RuleChain.emptyRuleChain()); 78fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin finalizerChecker = new BiConsumer<Object, Integer>() { 79fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin @Override 80fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin public void accept(Object o, Integer integer) { 81fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin // Do nothing. 82fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin } 83fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin }; 84fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin } 85fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin 86fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin LEAKAGE_DETECTOR_RULE = leakageDetectorRule; 87fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin FINALIZER_CHECKER = finalizerChecker; 88fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin } 89fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin 90fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin @SuppressWarnings("unchecked") 91fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin private static BiConsumer<Object, Integer> getFinalizerChecker(Class<?> closeGuardSupportClass) 92fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin throws ReflectiveOperationException { 93fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin Method method = closeGuardSupportClass.getMethod("getFinalizerChecker"); 94fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin return (BiConsumer<Object, Integer>) method.invoke(null); 95fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin } 96fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin 97fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin /** 98fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin * @return the {@link LeakageDetectorRule} 99fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin */ 100fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin public static LeakageDetectorRule getRule() { 101fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin return LEAKAGE_DETECTOR_RULE; 102fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin } 103fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin 104fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin /** 105fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin * A {@link TestRule} that will fail a test if it detects any resources that were allocated 106fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin * during the test but were not released. 107fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin * 108fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin * <p>This only tracks resources that were allocated on the test thread, although it does not 109fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin * care what thread they were released on. This avoids flaky false positives where a background 110fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin * thread allocates a resource during a test but releases it after the test. 111fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin * 112fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin * <p>It is still possible to have a false positive in the case where the test causes a caching 113fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin * mechanism to open a resource and hold it open past the end of the test. In that case if there 114fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin * is no way to clear the cached data then it should be relatively simple to move the code that 115fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin * invokes the caching mechanism to outside the scope of this rule. i.e. 116fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin * 11788df7911980a895f9379d9a0e4cbf46aaadf90d0Paul Duffin * <pre> 11888df7911980a895f9379d9a0e4cbf46aaadf90d0Paul Duffin * {@code @Rule} 119fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin * public final TestRule ruleChain = org.junit.rules.RuleChain 120fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin * .outerRule(new ...invoke caching mechanism...) 12188df7911980a895f9379d9a0e4cbf46aaadf90d0Paul Duffin * .around(ResourceLeakageDetector.getRule()); 12288df7911980a895f9379d9a0e4cbf46aaadf90d0Paul Duffin * </pre> 123fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin */ 124fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin public static class LeakageDetectorRule implements TestRule { 125fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin 126fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin private final TestRule leakageDetectorRule; 12788df7911980a895f9379d9a0e4cbf46aaadf90d0Paul Duffin private boolean leakageDetectionEnabledForTest; 128fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin 129fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin private LeakageDetectorRule(TestRule leakageDetectorRule) { 130fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin this.leakageDetectorRule = leakageDetectorRule; 131fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin } 132fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin 133fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin @Override 134fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin public Statement apply(Statement base, Description description) { 13527604018f783bf6354a13870b3e7785edca69b5fPaul Duffin // Make the resource leakage detector rule optional based on the presence of an 13627604018f783bf6354a13870b3e7785edca69b5fPaul Duffin // annotation. 13727604018f783bf6354a13870b3e7785edca69b5fPaul Duffin if (description.getAnnotation(DisableResourceLeakageDetection.class) != null) { 13888df7911980a895f9379d9a0e4cbf46aaadf90d0Paul Duffin leakageDetectionEnabledForTest = false; 13927604018f783bf6354a13870b3e7785edca69b5fPaul Duffin return base; 14027604018f783bf6354a13870b3e7785edca69b5fPaul Duffin } else { 14188df7911980a895f9379d9a0e4cbf46aaadf90d0Paul Duffin leakageDetectionEnabledForTest = true; 14227604018f783bf6354a13870b3e7785edca69b5fPaul Duffin return leakageDetectorRule.apply(base, description); 14327604018f783bf6354a13870b3e7785edca69b5fPaul Duffin } 144fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin } 145fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin 146fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin /** 147fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin * Ensure that when the supplied object is finalized that it detects the expected number of 148fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin * unreleased resources. 149fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin * 150fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin * <p>This helps ensure that classes which own resources protected using {@code CloseGuard} 151fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin * support leakage detection. 152fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin * 15388df7911980a895f9379d9a0e4cbf46aaadf90d0Paul Duffin * <p>This must only be called as part of the currently running test and the test must not 15488df7911980a895f9379d9a0e4cbf46aaadf90d0Paul Duffin * be annotated with {@link DisableResourceLeakageDetection} as that will disable leakage 15588df7911980a895f9379d9a0e4cbf46aaadf90d0Paul Duffin * detection. Attempting to use it with leakage detection disabled by the annotation will 15688df7911980a895f9379d9a0e4cbf46aaadf90d0Paul Duffin * result in a test failure. 157fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin * 15888df7911980a895f9379d9a0e4cbf46aaadf90d0Paul Duffin * <p>Use as follows, 'open' and 'close' refer to the methods in {@code CloseGuard}: 159fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin * <pre> 16088df7911980a895f9379d9a0e4cbf46aaadf90d0Paul Duffin * public class ResourceTest { 16188df7911980a895f9379d9a0e4cbf46aaadf90d0Paul Duffin * {@code @Rule} 16288df7911980a895f9379d9a0e4cbf46aaadf90d0Paul Duffin * public LeakageDetectorRule leakageDetectorRule = ResourceLeakageDetector.getRule(); 16388df7911980a895f9379d9a0e4cbf46aaadf90d0Paul Duffin * 16488df7911980a895f9379d9a0e4cbf46aaadf90d0Paul Duffin * {@code @Test} 16588df7911980a895f9379d9a0e4cbf46aaadf90d0Paul Duffin * public void testAutoCloseableResourceIsProtected() { 16688df7911980a895f9379d9a0e4cbf46aaadf90d0Paul Duffin * try (AutoCloseable object = ...open a protected resource...) { 16788df7911980a895f9379d9a0e4cbf46aaadf90d0Paul Duffin * leakageDetectorRule.assertUnreleasedResourceCount(object, 1); 16888df7911980a895f9379d9a0e4cbf46aaadf90d0Paul Duffin * } 16988df7911980a895f9379d9a0e4cbf46aaadf90d0Paul Duffin * } 170fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin * 17188df7911980a895f9379d9a0e4cbf46aaadf90d0Paul Duffin * {@code @Test} 17288df7911980a895f9379d9a0e4cbf46aaadf90d0Paul Duffin * public void testResourceIsProtected() { 17388df7911980a895f9379d9a0e4cbf46aaadf90d0Paul Duffin * NonAutoCloseable object = ...open a protected resource...; 17488df7911980a895f9379d9a0e4cbf46aaadf90d0Paul Duffin * leakageDetectorRule.assertUnreleasedResourceCount(object, 1); 17588df7911980a895f9379d9a0e4cbf46aaadf90d0Paul Duffin * object.release(); 17688df7911980a895f9379d9a0e4cbf46aaadf90d0Paul Duffin * } 17788df7911980a895f9379d9a0e4cbf46aaadf90d0Paul Duffin * } 178fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin * </pre> 179fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin * 18088df7911980a895f9379d9a0e4cbf46aaadf90d0Paul Duffin * <p>There are two test method templates, the one to use depends on whether the resource is 18188df7911980a895f9379d9a0e4cbf46aaadf90d0Paul Duffin * {@link AutoCloseable} or not. Each method tests the following:</p> 18288df7911980a895f9379d9a0e4cbf46aaadf90d0Paul Duffin * <ul> 18388df7911980a895f9379d9a0e4cbf46aaadf90d0Paul Duffin * <li>The {@code @Rule} will ensure that the test method does not leak any resources. That 18488df7911980a895f9379d9a0e4cbf46aaadf90d0Paul Duffin * will make sure that if it actually is protected by {@code CloseGuard} that it correctly 18588df7911980a895f9379d9a0e4cbf46aaadf90d0Paul Duffin * closes it. It does not actually ensure that it is protected. 18688df7911980a895f9379d9a0e4cbf46aaadf90d0Paul Duffin * <li>The call to this method will ensure that the resource is actually protected by 18788df7911980a895f9379d9a0e4cbf46aaadf90d0Paul Duffin * {@code CloseGuard}. 18888df7911980a895f9379d9a0e4cbf46aaadf90d0Paul Duffin * </ul> 18988df7911980a895f9379d9a0e4cbf46aaadf90d0Paul Duffin * 19088df7911980a895f9379d9a0e4cbf46aaadf90d0Paul Duffin * <p>The above tests will work on the reference implementation as this method does nothing 19188df7911980a895f9379d9a0e4cbf46aaadf90d0Paul Duffin * when {@code CloseGuard} is not supported. 19288df7911980a895f9379d9a0e4cbf46aaadf90d0Paul Duffin * 19388df7911980a895f9379d9a0e4cbf46aaadf90d0Paul Duffin * @param owner the object that owns the resource and uses {@code CloseGuard} object to 19488df7911980a895f9379d9a0e4cbf46aaadf90d0Paul Duffin * detect when the resource is not released. 19588df7911980a895f9379d9a0e4cbf46aaadf90d0Paul Duffin * @param expectedCount the expected number of unreleased resources, i.e. the number of 19688df7911980a895f9379d9a0e4cbf46aaadf90d0Paul Duffin * {@code CloseGuard} objects owned by the resource, and on which it calls 19788df7911980a895f9379d9a0e4cbf46aaadf90d0Paul Duffin * {@code CloseGuard.warnIfOpen()} in its {@link #finalize()} method; usually 1. 198fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin */ 199fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin public void assertUnreleasedResourceCount(Object owner, int expectedCount) { 20088df7911980a895f9379d9a0e4cbf46aaadf90d0Paul Duffin if (leakageDetectionEnabledForTest) { 20188df7911980a895f9379d9a0e4cbf46aaadf90d0Paul Duffin FINALIZER_CHECKER.accept(owner, expectedCount); 20288df7911980a895f9379d9a0e4cbf46aaadf90d0Paul Duffin } else { 20388df7911980a895f9379d9a0e4cbf46aaadf90d0Paul Duffin throw new IllegalStateException( 20488df7911980a895f9379d9a0e4cbf46aaadf90d0Paul Duffin "Does not work when leakage detection has been disabled; remove the " 20588df7911980a895f9379d9a0e4cbf46aaadf90d0Paul Duffin + "@DisableResourceLeakageDetection from the test method"); 20688df7911980a895f9379d9a0e4cbf46aaadf90d0Paul Duffin } 207fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin } 208fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin } 20927604018f783bf6354a13870b3e7785edca69b5fPaul Duffin 21027604018f783bf6354a13870b3e7785edca69b5fPaul Duffin /** 21127604018f783bf6354a13870b3e7785edca69b5fPaul Duffin * An annotation that indicates that the test should not be run with resource leakage detection 21227604018f783bf6354a13870b3e7785edca69b5fPaul Duffin * enabled. 21327604018f783bf6354a13870b3e7785edca69b5fPaul Duffin */ 21427604018f783bf6354a13870b3e7785edca69b5fPaul Duffin @Retention(RetentionPolicy.RUNTIME) 21527604018f783bf6354a13870b3e7785edca69b5fPaul Duffin @Target(ElementType.METHOD) 21627604018f783bf6354a13870b3e7785edca69b5fPaul Duffin public @interface DisableResourceLeakageDetection { 21727604018f783bf6354a13870b3e7785edca69b5fPaul Duffin 21827604018f783bf6354a13870b3e7785edca69b5fPaul Duffin /** 21927604018f783bf6354a13870b3e7785edca69b5fPaul Duffin * The explanation as to why resource leakage detection is disabled for this test. 22027604018f783bf6354a13870b3e7785edca69b5fPaul Duffin */ 22127604018f783bf6354a13870b3e7785edca69b5fPaul Duffin String why(); 22227604018f783bf6354a13870b3e7785edca69b5fPaul Duffin 22327604018f783bf6354a13870b3e7785edca69b5fPaul Duffin /** 22427604018f783bf6354a13870b3e7785edca69b5fPaul Duffin * The bug reference to the bug that was opened to fix the issue. 22527604018f783bf6354a13870b3e7785edca69b5fPaul Duffin */ 22627604018f783bf6354a13870b3e7785edca69b5fPaul Duffin String bug(); 22727604018f783bf6354a13870b3e7785edca69b5fPaul Duffin } 228fe0ee8ef8870338ad67ebfb6b62785e0cbdb325bPaul Duffin} 229