Home | History | Annotate | Download | only in system
      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
     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();
     44         @Test public void test() {
     45             CloseGuard closeGuard = CloseGuard.get();
     46             closeGuard.open("test resource");
     47             closeGuard.close();
     48         }
     49     }
     50 
     51     @Test
     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();
     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
     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();
     77         @Test public void test() {
     78             CloseGuard closeGuard = CloseGuard.get();
     79             closeGuard.open("test resource");
     80         }
     81     }
     82 
     83     @Test
     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();
     95         @Test public void test() {
     96             CloseGuard closeGuard = CloseGuard.get();
     97             closeGuard.open("test resource");
     98             fail("failure");
     99         }
    100     }
    101 
    102     @Test
    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
    116         public void test() {
    117             CloseGuardSupport.getFinalizerChecker().accept("not resource owner", 0);
    118         }
    119     }
    120 
    121     @Test
    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
    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
    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
    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 
    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