1 /*
2  * Copyright (C) 2018 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 
17 package android.testing;
18 
19 import static android.testing.DexmakerShareClassLoaderRule.DEXMAKER_SHARE_CLASSLOADER_PROPERTY;
20 
21 import static org.hamcrest.Matchers.is;
22 import static org.junit.Assert.assertThat;
23 import static org.junit.Assert.fail;
24 
25 import androidx.test.filters.SmallTest;
26 import androidx.test.runner.AndroidJUnit4;
27 
28 import org.junit.Before;
29 import org.junit.Test;
30 import org.junit.runner.RunWith;
31 import org.junit.runners.model.Statement;
32 
33 import java.util.ConcurrentModificationException;
34 
35 @SmallTest
36 @RunWith(AndroidJUnit4.class)
37 public class DexmakerShareClassLoaderRuleTest {
38 
39     // Intentionally not @Rule, so we have more control.
40     private final DexmakerShareClassLoaderRule mRule = new DexmakerShareClassLoaderRule();
41 
42     @Before
setUp()43     public void setUp() throws Exception {
44         System.clearProperty(DEXMAKER_SHARE_CLASSLOADER_PROPERTY);
45     }
46 
47     @Test
rule_setsProperty()48     public void rule_setsProperty() throws Throwable {
49         mRule.apply(ASSERT_STATEMENT, null).evaluate();
50     }
51 
52     @Test
rule_resetsProperty()53     public void rule_resetsProperty() throws Throwable {
54         mRule.apply(ASSERT_STATEMENT, null).evaluate();
55         assertThat(readProperty(), is(false));
56     }
57 
58     @Test
rule_resetsProperty_toExactValue()59     public void rule_resetsProperty_toExactValue() throws Throwable {
60         System.setProperty(DEXMAKER_SHARE_CLASSLOADER_PROPERTY, "asdf");
61         mRule.apply(ASSERT_STATEMENT, null).evaluate();
62         assertThat(System.getProperty(DEXMAKER_SHARE_CLASSLOADER_PROPERTY), is("asdf"));
63     }
64 
65     @Test
rule_preventsOtherThreadFromInterfering()66     public void rule_preventsOtherThreadFromInterfering() throws Throwable {
67         mRule.apply(new Statement() {
68             @Override
69             public void evaluate() throws Throwable {
70                 assertThat(readProperty(), is(true));
71 
72                 final Throwable[] thrown = new Throwable[1];
73                 final Thread t = new Thread(() -> {
74                     try {
75                         new DexmakerShareClassLoaderRule().apply(ASSERT_STATEMENT, null).evaluate();
76                         fail("Expected a ConcurrentModificationException");
77                     } catch (ConcurrentModificationException e) {
78                         // Success.
79                     } catch (Throwable tr) {
80                         thrown[0] = tr;
81                     }
82                 });
83                 t.start();
84                 t.join();
85 
86                 if (thrown[0] != null) {
87                     throw  thrown[0];
88                 }
89             }
90         }, null).evaluate();
91         assertThat(readProperty(), is(false));
92     }
93 
94     @Test
rule_isReentrant()95     public void rule_isReentrant() throws Throwable {
96         mRule.apply(new Statement() {
97             @Override
98             public void evaluate() throws Throwable {
99                 assertThat(readProperty(), is(true));
100                 new DexmakerShareClassLoaderRule().apply(ASSERT_STATEMENT, null).evaluate();
101                 assertThat(readProperty(), is(true));
102             }
103         }, null).evaluate();
104         assertThat(readProperty(), is(false));
105     }
106 
readProperty()107     private static boolean readProperty() {
108         return Boolean.parseBoolean(System.getProperty(DEXMAKER_SHARE_CLASSLOADER_PROPERTY));
109     }
110 
111     private static final Statement ASSERT_STATEMENT = new Statement() {
112         @Override
113         public void evaluate() throws Throwable {
114             assertThat(readProperty(), is(true));
115         }
116     };
117 
118 }
119