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 org.junit.Rule;
     19 import org.junit.Test;
     20 import org.junit.rules.TestRule;
     21 import org.junit.runner.Description;
     22 import org.junit.runners.model.Statement;
     23 
     24 import dalvik.system.CloseGuard;
     25 
     26 /**
     27  * Tests {@link CloseGuard}.
     28  */
     29 public class CloseGuardTest {
     30 
     31     /**
     32      * Resets the {@link CloseGuard#ENABLED} state back to the value it had when the test started.
     33      */
     34     @Rule
     35     public TestRule rule = this::preserveEnabledState;
     36 
     37     private Statement preserveEnabledState(final Statement base, Description description) {
     38         return new Statement() {
     39             @Override
     40             public void evaluate() throws Throwable {
     41                 boolean oldEnabledState = CloseGuard.isEnabled();
     42                 try {
     43                     base.evaluate();
     44                 } finally {
     45                     CloseGuard.setEnabled(oldEnabledState);
     46                 }
     47             }
     48         };
     49     }
     50 
     51     @Test
     52     public void testEnabled_NotOpen() throws Throwable {
     53         CloseGuard.setEnabled(true);
     54         ResourceOwner owner = new ResourceOwner();
     55         assertUnreleasedResources(owner, 0);
     56     }
     57 
     58     @Test
     59     public void testEnabled_OpenNotClosed() throws Throwable {
     60         CloseGuard.setEnabled(true);
     61         ResourceOwner owner = new ResourceOwner();
     62         owner.open();
     63         assertUnreleasedResources(owner, 1);
     64     }
     65 
     66     @Test
     67     public void testEnabled_OpenThenClosed() throws Throwable {
     68         CloseGuard.setEnabled(true);
     69         ResourceOwner owner = new ResourceOwner();
     70         owner.open();
     71         owner.close();
     72         assertUnreleasedResources(owner, 0);
     73     }
     74 
     75     @Test
     76     public void testEnabledWhenCreated_DisabledWhenOpen() throws Throwable {
     77         CloseGuard.setEnabled(true);
     78         ResourceOwner owner = new ResourceOwner();
     79         CloseGuard.setEnabled(false);
     80         owner.open();
     81 
     82         // Although the resource was not released it should not report it because CloseGuard was
     83         // not enabled when the CloseGuard was opened.
     84         assertUnreleasedResources(owner, 0);
     85     }
     86 
     87     @Test
     88     public void testEnabledWhenOpened_DisabledWhenFinalized() throws Throwable {
     89         CloseGuard.setEnabled(true);
     90         ResourceOwner owner = new ResourceOwner();
     91         owner.open();
     92         CloseGuard.setEnabled(false);
     93 
     94         // We report if CloseGuard was enabled on open.
     95         assertUnreleasedResources(owner, 1);
     96     }
     97 
     98     @Test
     99     public void testDisabled_NotOpen() throws Throwable {
    100         CloseGuard.setEnabled(false);
    101         ResourceOwner owner = new ResourceOwner();
    102         assertUnreleasedResources(owner, 0);
    103     }
    104 
    105     @Test
    106     public void testDisabled_OpenNotClosed() throws Throwable {
    107         CloseGuard.setEnabled(false);
    108         ResourceOwner owner = new ResourceOwner();
    109         owner.open();
    110         assertUnreleasedResources(owner, 0);
    111     }
    112 
    113     @Test
    114     public void testDisabled_OpenThenClosed() throws Throwable {
    115         CloseGuard.setEnabled(false);
    116         ResourceOwner owner = new ResourceOwner();
    117         owner.open();
    118         owner.close();
    119         assertUnreleasedResources(owner, 0);
    120     }
    121 
    122     @Test
    123     public void testDisabledWhenCreated_EnabledWhenOpen() throws Throwable {
    124         CloseGuard.setEnabled(false);
    125         ResourceOwner owner = new ResourceOwner();
    126         CloseGuard.setEnabled(true);
    127         owner.open();
    128 
    129         // The enabled state only matters during the open call.
    130         assertUnreleasedResources(owner, 1);
    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