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 */ 16 package libcore.dalvik.system; 17 18 import java.util.Collections; 19 import java.util.List; 20 import org.junit.Rule; 21 import org.junit.Test; 22 import org.junit.rules.TestRule; 23 import org.junit.runner.JUnitCore; 24 import org.junit.runner.RunWith; 25 import org.junit.runner.notification.Failure; 26 import org.junit.runners.JUnit4; 27 28 import dalvik.system.CloseGuard; 29 30 import static org.junit.Assert.assertEquals; 31 import static org.junit.Assert.fail; 32 33 @RunWith(JUnit4.class) 34 public class CloseGuardSupportTest { 35 36 @Test testDoesReleaseResource()37 public void testDoesReleaseResource() { 38 List<Failure> failures = JUnitCore.runClasses(DoesReleaseResource.class).getFailures(); 39 assertEquals(Collections.emptyList(), failures); 40 } 41 42 public static class DoesReleaseResource { 43 @Rule public TestRule rule = CloseGuardSupport.getRule(); test()44 @Test public void test() { 45 CloseGuard closeGuard = CloseGuard.get(); 46 closeGuard.open("test resource"); 47 closeGuard.close(); 48 } 49 } 50 51 @Test testDoesReleaseResourceTwice()52 public void testDoesReleaseResourceTwice() { 53 List<Failure> failures = JUnitCore.runClasses(DoesReleaseResourceTwice.class).getFailures(); 54 assertEquals(Collections.emptyList(), failures); 55 } 56 57 public static class DoesReleaseResourceTwice { 58 @Rule public TestRule rule = CloseGuardSupport.getRule(); test()59 @Test public void test() { 60 CloseGuard closeGuard = CloseGuard.get(); 61 closeGuard.open("test resource"); 62 closeGuard.close(); 63 closeGuard.close(); 64 } 65 } 66 67 @Test testDoesNotReleaseResource()68 public void testDoesNotReleaseResource() { 69 List<Failure> failures = JUnitCore.runClasses(DoesNotReleaseResource.class).getFailures(); 70 assertEquals("Failure count", 1, failures.size()); 71 Failure failure = failures.get(0); 72 checkResourceNotReleased(failure, "Unreleased resources found in test"); 73 } 74 75 public static class DoesNotReleaseResource { 76 @Rule public TestRule rule = CloseGuardSupport.getRule(); test()77 @Test public void test() { 78 CloseGuard closeGuard = CloseGuard.get(); 79 closeGuard.open("test resource"); 80 } 81 } 82 83 @Test testDoesNotReleaseResourceDueToFailure()84 public void testDoesNotReleaseResourceDueToFailure() { 85 List<Failure> failures = JUnitCore 86 .runClasses(DoesNotReleaseResourceDueToFailure.class) 87 .getFailures(); 88 assertEquals("Failure count", 1, failures.size()); 89 Failure failure = failures.get(0); 90 checkResourceNotReleased(failure, "failure"); 91 } 92 93 public static class DoesNotReleaseResourceDueToFailure { 94 @Rule public TestRule rule = CloseGuardSupport.getRule(); test()95 @Test public void test() { 96 CloseGuard closeGuard = CloseGuard.get(); 97 closeGuard.open("test resource"); 98 fail("failure"); 99 } 100 } 101 102 @Test testResourceOwnerDoesNotOverrideFinalize()103 public void testResourceOwnerDoesNotOverrideFinalize() { 104 List<Failure> failures = JUnitCore 105 .runClasses(ResourceOwnerDoesNotOverrideFinalize.class) 106 .getFailures(); 107 assertEquals("Failure count", 1, failures.size()); 108 Failure failure = failures.get(0); 109 assertEquals("Class java.lang.String does not have a finalize() method", 110 failure.getMessage()); 111 } 112 113 public static class ResourceOwnerDoesNotOverrideFinalize { 114 @Rule public TestRule rule = CloseGuardSupport.getRule(); 115 @Test test()116 public void test() { 117 CloseGuardSupport.getFinalizerChecker().accept("not resource owner", 0); 118 } 119 } 120 121 @Test testResourceOwnerOverridesFinalizeButDoesNotReportLeak()122 public void testResourceOwnerOverridesFinalizeButDoesNotReportLeak() { 123 List<Failure> failures = JUnitCore 124 .runClasses(ResourceOwnerOverridesFinalizeButDoesNotReportLeak.class) 125 .getFailures(); 126 assertEquals("Failure count", 1, failures.size()); 127 Failure failure = failures.get(0); 128 assertEquals("Expected 1 unreleased resources, found 0;" 129 + " see suppressed exceptions for details", 130 failure.getMessage()); 131 } 132 133 public static class ResourceOwnerOverridesFinalizeButDoesNotReportLeak { 134 @Rule public TestRule rule = CloseGuardSupport.getRule(); 135 @Test test()136 public void test() { 137 CloseGuardSupport.getFinalizerChecker().accept(new Object() { 138 @Override 139 protected void finalize() throws Throwable { 140 super.finalize(); 141 } 142 }, 1); 143 } 144 } 145 146 @Test testResourceOwnerOverridesFinalizeAndReportsLeak()147 public void testResourceOwnerOverridesFinalizeAndReportsLeak() { 148 List<Failure> failures = JUnitCore 149 .runClasses(ResourceOwnerOverridesFinalizeAndReportsLeak.class) 150 .getFailures(); 151 assertEquals("Failure count", 1, failures.size()); 152 Failure failure = failures.get(0); 153 checkResourceNotReleased(failure, "Unreleased resources found in test"); 154 } 155 156 public static class ResourceOwnerOverridesFinalizeAndReportsLeak { 157 @Rule public TestRule rule = CloseGuardSupport.getRule(); 158 @Test test()159 public void test() { 160 CloseGuardSupport.getFinalizerChecker().accept(new Object() { 161 private CloseGuard guard = CloseGuard.get(); 162 { 163 guard.open("test resource"); 164 } 165 @Override 166 protected void finalize() throws Throwable { 167 guard.warnIfOpen(); 168 super.finalize(); 169 } 170 }, 1); 171 } 172 } 173 checkResourceNotReleased(Failure failure, String expectedMessage)174 private void checkResourceNotReleased(Failure failure, String expectedMessage) { 175 @SuppressWarnings("ThrowableResultOfMethodCallIgnored") 176 Throwable exception = failure.getException(); 177 assertEquals(expectedMessage, exception.getMessage()); 178 Throwable[] suppressed = exception.getSuppressed(); 179 assertEquals("Suppressed count", 1, suppressed.length); 180 exception = suppressed[0]; 181 assertEquals("Explicit termination method 'test resource' not called", 182 exception.getMessage()); 183 } 184 } 185