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 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 /**
     25  * Tests {@link CloseGuard}.
     26  */
     27 public 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