[ApiModel] Update tests for checking class loading semantics
Bug: b/258270051
Change-Id: Iea900c58675693f552093f1bf020f85e5486db53
diff --git a/src/test/java/com/android/tools/r8/apimodel/ApiModelMockClassLoadingTest.java b/src/test/java/com/android/tools/r8/apimodel/ApiModelMockClassCheckCastTest.java
similarity index 67%
copy from src/test/java/com/android/tools/r8/apimodel/ApiModelMockClassLoadingTest.java
copy to src/test/java/com/android/tools/r8/apimodel/ApiModelMockClassCheckCastTest.java
index b80d79c..497011a 100644
--- a/src/test/java/com/android/tools/r8/apimodel/ApiModelMockClassLoadingTest.java
+++ b/src/test/java/com/android/tools/r8/apimodel/ApiModelMockClassCheckCastTest.java
@@ -1,4 +1,4 @@
-// Copyright (c) 2021, the R8 project authors. Please see the AUTHORS file
+// Copyright (c) 2022, the R8 project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
@@ -17,7 +17,6 @@
import com.android.tools.r8.TestCompilerBuilder;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.TestParametersCollection;
-import com.android.tools.r8.ToolHelper.DexVm;
import com.android.tools.r8.ToolHelper.DexVm.Version;
import com.android.tools.r8.utils.AndroidApiLevel;
import com.android.tools.r8.utils.codeinspector.CodeInspector;
@@ -28,7 +27,7 @@
import org.junit.runners.Parameterized.Parameters;
@RunWith(Parameterized.class)
-public class ApiModelMockClassLoadingTest extends TestBase {
+public class ApiModelMockClassCheckCastTest extends TestBase {
private final AndroidApiLevel mockLevel = AndroidApiLevel.M;
@@ -36,7 +35,7 @@
@Parameters(name = "{0}")
public static TestParametersCollection data() {
- return getTestParameters().withAllRuntimesAndApiLevels().build();
+ return getTestParameters().withAllRuntimes().withAllApiLevelsAlsoForCf().build();
}
private boolean isGreaterOrEqualToMockLevel() {
@@ -54,9 +53,17 @@
}
@Test
+ public void testReference() throws Exception {
+ assumeTrue(parameters.isCfRuntime() && parameters.getApiLevel().isEqualTo(AndroidApiLevel.B));
+ testForJvm()
+ .addProgramClasses(Main.class, TestClass.class)
+ .run(parameters.getRuntime(), Main.class)
+ .apply(this::checkOutput);
+ }
+
+ @Test
public void testD8Debug() throws Exception {
- assumeTrue(parameters.isDexRuntime());
- testForD8()
+ testForD8(parameters.getBackend())
.setMode(CompilationMode.DEBUG)
.apply(this::setupTestBuilder)
.compile()
@@ -68,8 +75,7 @@
@Test
public void testD8Release() throws Exception {
- assumeTrue(parameters.isDexRuntime());
- testForD8()
+ testForD8(parameters.getBackend())
.setMode(CompilationMode.RELEASE)
.apply(this::setupTestBuilder)
.compile()
@@ -94,12 +100,12 @@
private void checkOutput(SingleTestRunResult<?> runResult) {
if (isGreaterOrEqualToMockLevel()) {
- runResult.assertSuccessWithOutputLines("Hello World!");
- } else if (parameters.isDexRuntime()
- && parameters.asDexRuntime().getVm().isEqualTo(DexVm.ART_4_4_4_HOST)) {
- runResult.assertSuccessWithOutputLines("ClassNotFoundException");
+ runResult.assertSuccessWithOutputLines("false", "checkcast caused ClassCastException");
+ } else if (parameters.isCfRuntime()) {
+ runResult.assertSuccessWithOutputLines(
+ "instanceof caused NoClassDefFoundError", "checkcast caused NoClassDefFoundError");
} else {
- runResult.assertSuccessWithOutputLines("NoClassDefFoundError");
+ runResult.assertSuccessWithOutputLines("false", "checkcast caused ClassCastException");
}
runResult.applyIf(
!isGreaterOrEqualToMockLevel()
@@ -118,14 +124,22 @@
public static class TestClass {
@NeverInline
- public static void test() {
+ public static void testInstanceOf(Object o) {
try {
- Class.forName(LibraryClass.class.getName());
- System.out.println("Hello World!");
- } catch (ExceptionInInitializerError | NoClassDefFoundError er) {
- System.out.println("NoClassDefFoundError");
- } catch (ClassNotFoundException e) {
- System.out.println("ClassNotFoundException");
+ System.out.println(o instanceof LibraryClass);
+ } catch (NoClassDefFoundError ex) {
+ System.out.println("instanceof caused NoClassDefFoundError");
+ }
+ }
+
+ @NeverInline
+ public static void testCheckCast(Object o) {
+ try {
+ System.out.println(((LibraryClass) o).getClass().getName());
+ } catch (NoClassDefFoundError e) {
+ System.out.println("checkcast caused NoClassDefFoundError");
+ } catch (ClassCastException e) {
+ System.out.println("checkcast caused ClassCastException");
}
}
}
@@ -133,7 +147,15 @@
public static class Main {
public static void main(String[] args) {
- TestClass.test();
+ if (System.currentTimeMillis() > 0) {
+ Object o = new Object();
+ TestClass.testInstanceOf(o);
+ TestClass.testCheckCast(o);
+ } else {
+ LibraryClass libraryClass = new LibraryClass();
+ TestClass.testInstanceOf(libraryClass);
+ TestClass.testCheckCast(libraryClass);
+ }
}
}
}
diff --git a/src/test/java/com/android/tools/r8/apimodel/ApiModelMockClassLoadingTest.java b/src/test/java/com/android/tools/r8/apimodel/ApiModelMockClassLoadingByClassForNameTest.java
similarity index 75%
copy from src/test/java/com/android/tools/r8/apimodel/ApiModelMockClassLoadingTest.java
copy to src/test/java/com/android/tools/r8/apimodel/ApiModelMockClassLoadingByClassForNameTest.java
index b80d79c..88c21a7 100644
--- a/src/test/java/com/android/tools/r8/apimodel/ApiModelMockClassLoadingTest.java
+++ b/src/test/java/com/android/tools/r8/apimodel/ApiModelMockClassLoadingByClassForNameTest.java
@@ -17,7 +17,6 @@
import com.android.tools.r8.TestCompilerBuilder;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.TestParametersCollection;
-import com.android.tools.r8.ToolHelper.DexVm;
import com.android.tools.r8.ToolHelper.DexVm.Version;
import com.android.tools.r8.utils.AndroidApiLevel;
import com.android.tools.r8.utils.codeinspector.CodeInspector;
@@ -28,7 +27,7 @@
import org.junit.runners.Parameterized.Parameters;
@RunWith(Parameterized.class)
-public class ApiModelMockClassLoadingTest extends TestBase {
+public class ApiModelMockClassLoadingByClassForNameTest extends TestBase {
private final AndroidApiLevel mockLevel = AndroidApiLevel.M;
@@ -36,7 +35,7 @@
@Parameters(name = "{0}")
public static TestParametersCollection data() {
- return getTestParameters().withAllRuntimesAndApiLevels().build();
+ return getTestParameters().withAllRuntimes().withAllApiLevelsAlsoForCf().build();
}
private boolean isGreaterOrEqualToMockLevel() {
@@ -54,9 +53,17 @@
}
@Test
+ public void testReference() throws Exception {
+ assumeTrue(parameters.isCfRuntime() && parameters.getApiLevel().isEqualTo(AndroidApiLevel.B));
+ testForJvm()
+ .addProgramClasses(Main.class, TestClass.class)
+ .run(parameters.getRuntime(), Main.class)
+ .apply(this::checkOutput);
+ }
+
+ @Test
public void testD8Debug() throws Exception {
- assumeTrue(parameters.isDexRuntime());
- testForD8()
+ testForD8(parameters.getBackend())
.setMode(CompilationMode.DEBUG)
.apply(this::setupTestBuilder)
.compile()
@@ -68,8 +75,7 @@
@Test
public void testD8Release() throws Exception {
- assumeTrue(parameters.isDexRuntime());
- testForD8()
+ testForD8(parameters.getBackend())
.setMode(CompilationMode.RELEASE)
.apply(this::setupTestBuilder)
.compile()
@@ -95,10 +101,13 @@
private void checkOutput(SingleTestRunResult<?> runResult) {
if (isGreaterOrEqualToMockLevel()) {
runResult.assertSuccessWithOutputLines("Hello World!");
- } else if (parameters.isDexRuntime()
- && parameters.asDexRuntime().getVm().isEqualTo(DexVm.ART_4_4_4_HOST)) {
+ } else if (parameters.isDexRuntimeVersion(Version.V4_0_4)) {
+ // TODO(b/258270051): This should be ClassNotFoundException.
+ runResult.assertSuccessWithOutputLines("ExceptionInInitializerError");
+ } else if (parameters.isDexRuntimeVersion(Version.V4_4_4) || parameters.isCfRuntime()) {
runResult.assertSuccessWithOutputLines("ClassNotFoundException");
} else {
+ // TODO(b/258270051): This should be ClassNotFoundException.
runResult.assertSuccessWithOutputLines("NoClassDefFoundError");
}
runResult.applyIf(
@@ -120,9 +129,14 @@
@NeverInline
public static void test() {
try {
- Class.forName(LibraryClass.class.getName());
+ String className =
+ "com.android.tools.r8.apimodel.ApiModelMockClassLoadingByClassForNameTest$LibraryClass"
+ + (System.currentTimeMillis() == 0 ? "asdf" : "");
+ Class.forName(className);
System.out.println("Hello World!");
- } catch (ExceptionInInitializerError | NoClassDefFoundError er) {
+ } catch (ExceptionInInitializerError er) {
+ System.out.println("ExceptionInInitializerError");
+ } catch (NoClassDefFoundError er) {
System.out.println("NoClassDefFoundError");
} catch (ClassNotFoundException e) {
System.out.println("ClassNotFoundException");
@@ -134,6 +148,9 @@
public static void main(String[] args) {
TestClass.test();
+ if (System.currentTimeMillis() == 0) {
+ System.out.println(LibraryClass.class.getName());
+ }
}
}
}
diff --git a/src/test/java/com/android/tools/r8/apimodel/ApiModelMockClassLoadingTest.java b/src/test/java/com/android/tools/r8/apimodel/ApiModelMockClassLoadingByClassReferenceTest.java
similarity index 83%
rename from src/test/java/com/android/tools/r8/apimodel/ApiModelMockClassLoadingTest.java
rename to src/test/java/com/android/tools/r8/apimodel/ApiModelMockClassLoadingByClassReferenceTest.java
index b80d79c..91a8d74 100644
--- a/src/test/java/com/android/tools/r8/apimodel/ApiModelMockClassLoadingTest.java
+++ b/src/test/java/com/android/tools/r8/apimodel/ApiModelMockClassLoadingByClassReferenceTest.java
@@ -1,4 +1,4 @@
-// Copyright (c) 2021, the R8 project authors. Please see the AUTHORS file
+// Copyright (c) 2022, the R8 project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
@@ -17,7 +17,6 @@
import com.android.tools.r8.TestCompilerBuilder;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.TestParametersCollection;
-import com.android.tools.r8.ToolHelper.DexVm;
import com.android.tools.r8.ToolHelper.DexVm.Version;
import com.android.tools.r8.utils.AndroidApiLevel;
import com.android.tools.r8.utils.codeinspector.CodeInspector;
@@ -28,7 +27,7 @@
import org.junit.runners.Parameterized.Parameters;
@RunWith(Parameterized.class)
-public class ApiModelMockClassLoadingTest extends TestBase {
+public class ApiModelMockClassLoadingByClassReferenceTest extends TestBase {
private final AndroidApiLevel mockLevel = AndroidApiLevel.M;
@@ -36,7 +35,7 @@
@Parameters(name = "{0}")
public static TestParametersCollection data() {
- return getTestParameters().withAllRuntimesAndApiLevels().build();
+ return getTestParameters().withAllRuntimes().withAllApiLevelsAlsoForCf().build();
}
private boolean isGreaterOrEqualToMockLevel() {
@@ -54,9 +53,17 @@
}
@Test
+ public void testReference() throws Exception {
+ assumeTrue(parameters.isCfRuntime() && parameters.getApiLevel().isEqualTo(AndroidApiLevel.B));
+ testForJvm()
+ .addProgramClasses(Main.class, TestClass.class)
+ .run(parameters.getRuntime(), Main.class)
+ .apply(this::checkOutput);
+ }
+
+ @Test
public void testD8Debug() throws Exception {
- assumeTrue(parameters.isDexRuntime());
- testForD8()
+ testForD8(parameters.getBackend())
.setMode(CompilationMode.DEBUG)
.apply(this::setupTestBuilder)
.compile()
@@ -68,8 +75,7 @@
@Test
public void testD8Release() throws Exception {
- assumeTrue(parameters.isDexRuntime());
- testForD8()
+ testForD8(parameters.getBackend())
.setMode(CompilationMode.RELEASE)
.apply(this::setupTestBuilder)
.compile()
@@ -94,10 +100,7 @@
private void checkOutput(SingleTestRunResult<?> runResult) {
if (isGreaterOrEqualToMockLevel()) {
- runResult.assertSuccessWithOutputLines("Hello World!");
- } else if (parameters.isDexRuntime()
- && parameters.asDexRuntime().getVm().isEqualTo(DexVm.ART_4_4_4_HOST)) {
- runResult.assertSuccessWithOutputLines("ClassNotFoundException");
+ runResult.assertSuccessWithOutputLines(typeName(LibraryClass.class));
} else {
runResult.assertSuccessWithOutputLines("NoClassDefFoundError");
}
@@ -120,12 +123,9 @@
@NeverInline
public static void test() {
try {
- Class.forName(LibraryClass.class.getName());
- System.out.println("Hello World!");
+ System.out.println(new LibraryClass().getClass().getName());
} catch (ExceptionInInitializerError | NoClassDefFoundError er) {
System.out.println("NoClassDefFoundError");
- } catch (ClassNotFoundException e) {
- System.out.println("ClassNotFoundException");
}
}
}