1 /* 2 * Copyright (C) 2017 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 * in compliance with the License. You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software distributed under the License 10 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 * or implied. See the License for the specific language governing permissions and limitations under 12 * the License. 13 */ 14 package lockedregioncodeinjection; 15 16 import org.junit.Assert; 17 import org.junit.Test; 18 19 /** 20 * To run the unit tests: 21 * 22 * <pre> 23 * <code> 24 * set -x 25 * 26 * croot frameworks/base/tools/locked_region_code_injection 27 * 28 * # Clean 29 * mkdir -p out 30 * rm -fr out/* 31 * 32 * # Make booster 33 * javac -cp lib/asm-6.0_BETA.jar:lib/asm-commons-6.0_BETA.jar:lib/asm-tree-6.0_BETA.jar:lib/asm-analysis-6.0_BETA.jar:lib/guava-21.0.jar src/*/*.java -d out/ 34 * pushd out 35 * jar cfe lockedregioncodeinjection.jar lockedregioncodeinjection.Main */*.class 36 * popd 37 * 38 * # Make unit tests. 39 * javac -cp lib/junit-4.12.jar test/*/*.java -d out/ 40 * 41 * pushd out 42 * jar cfe test_input.jar lockedregioncodeinjection.Test */*.class 43 * popd 44 * 45 * # Run tool on unit tests. 46 * java -ea -cp lib/asm-6.0_BETA.jar:lib/asm-commons-6.0_BETA.jar:lib/asm-tree-6.0_BETA.jar:lib/asm-analysis-6.0_BETA.jar:lib/guava-21.0.jar:out/lockedregioncodeinjection.jar \ 47 * lockedregioncodeinjection.Main \ 48 * -i out/test_input.jar -o out/test_output.jar \ 49 * --targets 'Llockedregioncodeinjection/TestTarget;' \ 50 * --pre 'lockedregioncodeinjection/TestTarget.boost' \ 51 * --post 'lockedregioncodeinjection/TestTarget.unboost' 52 * 53 * # Run unit tests. 54 * java -ea -cp lib/hamcrest-core-1.3.jar:lib/junit-4.12.jar:out/test_output.jar \ 55 * org.junit.runner.JUnitCore lockedregioncodeinjection.TestMain 56 * </code> 57 * </pre> 58 */ 59 public class TestMain { 60 @Test testSimpleSynchronizedBlock()61 public void testSimpleSynchronizedBlock() { 62 TestTarget.resetCount(); 63 TestTarget t = new TestTarget(); 64 65 Assert.assertEquals(TestTarget.boostCount, 0); 66 Assert.assertEquals(TestTarget.unboostCount, 0); 67 Assert.assertEquals(TestTarget.unboostCount, 0); 68 69 synchronized (t) { 70 Assert.assertEquals(TestTarget.boostCount, 1); 71 Assert.assertEquals(TestTarget.unboostCount, 0); 72 TestTarget.invoke(); 73 } 74 75 Assert.assertEquals(TestTarget.boostCount, 1); 76 Assert.assertEquals(TestTarget.unboostCount, 1); 77 Assert.assertEquals(TestTarget.invokeCount, 1); 78 } 79 80 @Test testSimpleSynchronizedMethod()81 public void testSimpleSynchronizedMethod() { 82 TestTarget.resetCount(); 83 TestTarget t = new TestTarget(); 84 85 Assert.assertEquals(TestTarget.boostCount, 0); 86 Assert.assertEquals(TestTarget.unboostCount, 0); 87 88 t.synchronizedCall(); 89 90 Assert.assertEquals(TestTarget.boostCount, 1); 91 Assert.assertEquals(TestTarget.unboostCount, 1); 92 Assert.assertEquals(TestTarget.invokeCount, 1); 93 } 94 95 @Test testSimpleSynchronizedMethod2()96 public void testSimpleSynchronizedMethod2() { 97 TestTarget.resetCount(); 98 TestTarget t = new TestTarget(); 99 100 Assert.assertEquals(TestTarget.boostCount, 0); 101 Assert.assertEquals(TestTarget.unboostCount, 0); 102 103 t.synchronizedCallReturnInt(); 104 105 Assert.assertEquals(TestTarget.boostCount, 1); 106 Assert.assertEquals(TestTarget.unboostCount, 1); 107 Assert.assertEquals(TestTarget.invokeCount, 1); 108 } 109 110 @Test testSimpleSynchronizedMethod3()111 public void testSimpleSynchronizedMethod3() { 112 TestTarget.resetCount(); 113 TestTarget t = new TestTarget(); 114 115 Assert.assertEquals(TestTarget.boostCount, 0); 116 Assert.assertEquals(TestTarget.unboostCount, 0); 117 118 t.synchronizedCallReturnObject(); 119 120 Assert.assertEquals(TestTarget.boostCount, 1); 121 Assert.assertEquals(TestTarget.unboostCount, 1); 122 Assert.assertEquals(TestTarget.invokeCount, 1); 123 } 124 125 @SuppressWarnings("unused") 126 @Test testCaughtException()127 public void testCaughtException() { 128 TestTarget.resetCount(); 129 TestTarget t = new TestTarget(); 130 boolean caughtException = false; 131 132 Assert.assertEquals(TestTarget.boostCount, 0); 133 Assert.assertEquals(TestTarget.unboostCount, 0); 134 Assert.assertEquals(TestTarget.unboostCount, 0); 135 136 try { 137 synchronized (t) { 138 Assert.assertEquals(TestTarget.boostCount, 1); 139 Assert.assertEquals(TestTarget.unboostCount, 0); 140 if (true) { 141 throw new RuntimeException(); 142 } 143 TestTarget.invoke(); 144 } 145 } catch (Throwable e) { 146 caughtException = true; 147 } 148 149 Assert.assertEquals(TestTarget.boostCount, 1); 150 Assert.assertEquals(TestTarget.unboostCount, 1); 151 Assert.assertEquals(TestTarget.invokeCount, 0); // Not called 152 Assert.assertTrue(caughtException); 153 } 154 155 @SuppressWarnings("unused") testUncaughtException()156 private void testUncaughtException() { 157 TestTarget t = new TestTarget(); 158 synchronized (t) { 159 if (true) { 160 throw new RuntimeException(); 161 } 162 TestTarget.invoke(); 163 } 164 } 165 166 @SuppressWarnings("unused") 167 @Test testHandledFinally()168 public void testHandledFinally() { 169 TestTarget.resetCount(); 170 try { 171 testUncaughtException(); 172 } catch (Throwable t) { 173 174 } 175 Assert.assertEquals(TestTarget.boostCount, 1); 176 Assert.assertEquals(TestTarget.unboostCount, 1); 177 Assert.assertEquals(TestTarget.invokeCount, 0); // Not called 178 } 179 180 @Test testNestedSynchronizedBlock()181 public void testNestedSynchronizedBlock() { 182 TestTarget.resetCount(); 183 TestTarget t = new TestTarget(); 184 185 Assert.assertEquals(TestTarget.boostCount, 0); 186 Assert.assertEquals(TestTarget.unboostCount, 0); 187 Assert.assertEquals(TestTarget.unboostCount, 0); 188 189 synchronized (t) { 190 synchronized (t) { 191 synchronized (t) { 192 synchronized (t) { 193 synchronized (t) { 194 synchronized (t) { 195 Assert.assertEquals(TestTarget.boostCount, 6); 196 Assert.assertEquals(TestTarget.unboostCount, 0); 197 TestTarget.invoke(); 198 } 199 Assert.assertEquals(TestTarget.unboostCount, 1); 200 } 201 Assert.assertEquals(TestTarget.unboostCount, 2); 202 } 203 Assert.assertEquals(TestTarget.unboostCount, 3); 204 } 205 Assert.assertEquals(TestTarget.unboostCount, 4); 206 } 207 Assert.assertEquals(TestTarget.unboostCount, 5); 208 } 209 210 Assert.assertEquals(TestTarget.boostCount, 6); 211 Assert.assertEquals(TestTarget.unboostCount, 6); 212 Assert.assertEquals(TestTarget.invokeCount, 1); 213 } 214 215 @Test testMethodWithControlFlow()216 public void testMethodWithControlFlow() { 217 TestTarget.resetCount(); 218 TestTarget t = new TestTarget(); 219 220 Assert.assertEquals(TestTarget.boostCount, 0); 221 Assert.assertEquals(TestTarget.unboostCount, 0); 222 223 if ((t.hashCode() + " ").contains("1")) { 224 t.synchronizedCall(); 225 } else { 226 t.synchronizedCall(); 227 } 228 229 // Should only be boosted once. 230 Assert.assertEquals(TestTarget.boostCount, 1); 231 Assert.assertEquals(TestTarget.unboostCount, 1); 232 Assert.assertEquals(TestTarget.invokeCount, 1); 233 } 234 235 @Test testUnboostThatThrows()236 public void testUnboostThatThrows() { 237 TestTarget.resetCount(); 238 TestTarget t = new TestTarget(); 239 boolean asserted = false; 240 241 Assert.assertEquals(TestTarget.boostCount, 0); 242 Assert.assertEquals(TestTarget.unboostCount, 0); 243 244 try { 245 t.synchronizedThrowsOnUnboost(); 246 } catch (RuntimeException e) { 247 asserted = true; 248 } 249 250 Assert.assertEquals(asserted, true); 251 Assert.assertEquals(TestTarget.boostCount, 1); 252 Assert.assertEquals(TestTarget.unboostCount, 0); 253 Assert.assertEquals(TestTarget.invokeCount, 1); 254 } 255 256 } 257