Update api stubbing tests to add class to bootclasspath
Change-Id: Ia7daf0b605cbee7333c0f746bcbbe2697ba6b885
diff --git a/src/test/java/com/android/tools/r8/R8RunArtTestsTest.java b/src/test/java/com/android/tools/r8/R8RunArtTestsTest.java
index f0c648b..ccdd0ca 100644
--- a/src/test/java/com/android/tools/r8/R8RunArtTestsTest.java
+++ b/src/test/java/com/android/tools/r8/R8RunArtTestsTest.java
@@ -2237,7 +2237,7 @@
builder.appendArtOption("-Xnoimage-dex2oat");
}
for (String s : ToolHelper.getBootLibs(dexVm)) {
- builder.appendBootClassPath(new File(s).getCanonicalPath());
+ builder.appendBootClasspath(new File(s).getCanonicalPath());
}
builder.setMainClass(JUNIT_TEST_RUNNER);
builder.appendProgramArgument(fullClassName);
diff --git a/src/test/java/com/android/tools/r8/R8TestCompileResult.java b/src/test/java/com/android/tools/r8/R8TestCompileResult.java
index 0480694..b96cef4 100644
--- a/src/test/java/com/android/tools/r8/R8TestCompileResult.java
+++ b/src/test/java/com/android/tools/r8/R8TestCompileResult.java
@@ -179,7 +179,7 @@
for (int i = 2; i < args.length; i++) {
args[i] = featureDependencies[i - 2].toString();
}
- return runArt(runtime, additionalRunClassPath, mainClassSubject.getFinalName(), args);
+ return runArt(runtime, mainClassSubject.getFinalName(), args);
}
public String getProguardMap() {
diff --git a/src/test/java/com/android/tools/r8/TestCompileResult.java b/src/test/java/com/android/tools/r8/TestCompileResult.java
index 9ab97e7..af079d9 100644
--- a/src/test/java/com/android/tools/r8/TestCompileResult.java
+++ b/src/test/java/com/android/tools/r8/TestCompileResult.java
@@ -33,6 +33,7 @@
import com.android.tools.r8.utils.codeinspector.CodeInspector;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ObjectArrays;
+import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Path;
@@ -56,6 +57,7 @@
public final int minApiLevel;
private final OutputMode outputMode;
final List<Path> additionalRunClassPath = new ArrayList<>();
+ final List<Path> additionalBootClasspath = new ArrayList<>();
final List<String> vmArguments = new ArrayList<>();
private boolean withArt6Plus64BitsLib = false;
private boolean withArtFrameworks = true;
@@ -164,12 +166,10 @@
case DEX:
return runArt(
new DexRuntime(ToolHelper.getDexVm()),
- additionalRunClassPath,
mainClassSubject.getFinalName());
case CF:
return runJava(
TestRuntime.getDefaultJavaRuntime(),
- additionalRunClassPath,
mainClassSubject.getFinalName());
default:
throw new Unreachable();
@@ -207,12 +207,11 @@
}
assertThat("Did you forget a keep rule for the main method?", mainClassSubject, isPresent());
if (runtime.isDex()) {
- return runArt(runtime, additionalRunClassPath, mainClassSubject.getFinalName(), args);
+ return runArt(runtime, mainClassSubject.getFinalName(), args);
}
assert runtime.isCf();
return runJava(
runtime,
- additionalRunClassPath,
ObjectArrays.concat(mainClassSubject.getFinalName(), args));
}
@@ -256,6 +255,38 @@
}
}
+ public CR addBootClasspathClasses(Class<?>... classes) throws Exception {
+ return addBootClasspathClasses(Arrays.asList(classes));
+ }
+
+ public CR addBootClasspathClasses(List<Class<?>> classes) throws Exception {
+ if (getBackend() == Backend.DEX) {
+ additionalBootClasspath.add(
+ testForD8(state.getTempFolder())
+ .addProgramClasses(classes)
+ .setMinApi(minApiLevel)
+ .compile()
+ .writeToZip());
+ return self();
+ }
+ assert getBackend() == Backend.CF;
+ try {
+ Path path = state.getNewTempFolder().resolve("runtime-classes.jar");
+ ArchiveConsumer consumer = new ArchiveConsumer(path);
+ for (Class<?> clazz : classes) {
+ consumer.accept(
+ ByteDataView.of(ToolHelper.getClassAsBytes(clazz)),
+ DescriptorUtils.javaTypeToDescriptor(clazz.getTypeName()),
+ null);
+ }
+ consumer.finished(null);
+ additionalBootClasspath.add(path);
+ return self();
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
public CR addDesugaredCoreLibraryRunClassPath(
Function<AndroidApiLevel, Path> classPathSupplier, AndroidApiLevel minAPILevel) {
addRunClasspathFiles(classPathSupplier.apply(minAPILevel));
@@ -523,30 +554,29 @@
}
}
- private RR runJava(TestRuntime runtime, List<Path> additionalClassPath, String... arguments)
- throws IOException {
+ private RR runJava(TestRuntime runtime, String... arguments) throws IOException {
assert runtime != null;
Path out = state.getNewTempFolder().resolve("out.zip");
app.writeToZip(out, OutputMode.ClassFile);
- List<Path> classPath = ImmutableList.<Path>builder()
- .addAll(additionalClassPath)
- .add(out)
- .build();
- ProcessResult result = ToolHelper.runJava(runtime.asCf(), vmArguments, classPath, arguments);
+ List<Path> classPath =
+ ImmutableList.<Path>builder().addAll(additionalRunClassPath).add(out).build();
+ ProcessResult result =
+ ToolHelper.runJava(
+ runtime.asCf(), vmArguments, additionalBootClasspath, classPath, arguments);
return createRunResult(runtime, result);
}
- RR runArt(
- TestRuntime runtime, List<Path> additionalClassPath, String mainClass, String... arguments)
- throws IOException {
+ RR runArt(TestRuntime runtime, String mainClass, String... arguments) throws IOException {
DexVm vm = runtime.asDex().getVm();
// TODO(b/127785410): Always assume a non-null runtime.
Path out = state.getNewTempFolder().resolve("out.zip");
app.writeToZip(out, OutputMode.DexIndexed);
- List<String> classPath = ImmutableList.<String>builder()
- .addAll(additionalClassPath.stream().map(Path::toString).collect(Collectors.toList()))
- .add(out.toString())
- .build();
+ List<String> classPath =
+ ImmutableList.<String>builder()
+ .addAll(
+ additionalRunClassPath.stream().map(Path::toString).collect(Collectors.toList()))
+ .add(out.toString())
+ .build();
Consumer<ArtCommandBuilder> commandConsumer =
withArt6Plus64BitsLib && vm.getVersion().isNewerThanOrEqual(DexVm.Version.V6_0_1)
? builder -> builder.appendArtOption("--64")
@@ -554,6 +584,22 @@
commandConsumer =
commandConsumer.andThen(
builder -> {
+ if (!additionalBootClasspath.isEmpty()) {
+ DexVm dexVm = runtime.asDex().getVm();
+ if (dexVm.isNewerThan(DexVm.ART_4_4_4_HOST)) {
+ builder.appendArtOption("-Ximage:/system/non/existent/image.art");
+ builder.appendArtOption("-Xnoimage-dex2oat");
+ }
+ try {
+ for (String s : ToolHelper.getBootLibs(dexVm)) {
+ builder.appendBootClasspath(new File(s).getCanonicalPath());
+ }
+ } catch (Exception e) {
+ throw new RuntimeException();
+ }
+ additionalBootClasspath.forEach(
+ path -> builder.appendBootClasspath(path.toString()));
+ }
for (String vmArgument : vmArguments) {
builder.appendArtOption(vmArgument);
}
diff --git a/src/test/java/com/android/tools/r8/ToolHelper.java b/src/test/java/com/android/tools/r8/ToolHelper.java
index 2d0cc12..57fabd1 100644
--- a/src/test/java/com/android/tools/r8/ToolHelper.java
+++ b/src/test/java/com/android/tools/r8/ToolHelper.java
@@ -422,7 +422,7 @@
protected List<String> classpaths = new ArrayList<>();
protected String mainClass;
protected List<String> programArguments = new ArrayList<>();
- protected List<String> bootClassPaths = new ArrayList<>();
+ protected List<String> bootClasspaths = new ArrayList<>();
protected String executionDirectory;
public CommandBuilder appendArtOption(String option) {
@@ -450,8 +450,8 @@
return this;
}
- public CommandBuilder appendBootClassPath(String lib) {
- bootClassPaths.add(lib);
+ public CommandBuilder appendBootClasspath(String lib) {
+ bootClasspaths.add(lib);
return this;
}
@@ -475,13 +475,13 @@
builder.append(entry.getValue());
result.add(builder.toString());
}
+ if (!bootClasspaths.isEmpty()) {
+ result.add("-Xbootclasspath:" + String.join(":", bootClasspaths));
+ }
if (!classpaths.isEmpty()) {
result.add("-cp");
result.add(String.join(":", classpaths));
}
- if (!bootClassPaths.isEmpty()) {
- result.add("-Xbootclasspath:" + String.join(":", bootClassPaths));
- }
if (mainClass != null) {
result.add(mainClass);
}
@@ -555,7 +555,7 @@
.setVmOptions(options)
.setSystemProperties(systemProperties)
.setClasspath(toFileList(classpaths))
- .setBootClasspath(toFileList(bootClassPaths))
+ .setBootClasspath(toFileList(bootClasspaths))
.setMainClass(mainClass)
.setProgramArguments(programArguments);
}
@@ -1416,12 +1416,28 @@
public static ProcessResult runJava(
CfRuntime runtime, List<String> vmArgs, List<Path> classpath, String... args)
throws IOException {
- String cp =
- classpath.stream().map(Path::toString).collect(Collectors.joining(CLASSPATH_SEPARATOR));
+ return runJava(runtime, vmArgs, ImmutableList.of(), classpath, args);
+ }
+
+ public static ProcessResult runJava(
+ CfRuntime runtime,
+ List<String> vmArgs,
+ List<Path> bootClasspaths,
+ List<Path> classpath,
+ String... args)
+ throws IOException {
List<String> cmdline = new ArrayList<>(Arrays.asList(runtime.getJavaExecutable().toString()));
cmdline.addAll(vmArgs);
+ if (!bootClasspaths.isEmpty()) {
+ cmdline.add(
+ "-Xbootclasspath/a:"
+ + bootClasspaths.stream()
+ .map(Path::toString)
+ .collect(Collectors.joining(CLASSPATH_SEPARATOR)));
+ }
cmdline.add("-cp");
- cmdline.add(cp);
+ cmdline.add(
+ classpath.stream().map(Path::toString).collect(Collectors.joining(CLASSPATH_SEPARATOR)));
cmdline.addAll(Arrays.asList(args));
ProcessBuilder builder = new ProcessBuilder(cmdline);
return runProcess(builder);
diff --git a/src/test/java/com/android/tools/r8/apimodel/ApiModelMockClassTest.java b/src/test/java/com/android/tools/r8/apimodel/ApiModelMockClassTest.java
index 97351d8..4125cc2 100644
--- a/src/test/java/com/android/tools/r8/apimodel/ApiModelMockClassTest.java
+++ b/src/test/java/com/android/tools/r8/apimodel/ApiModelMockClassTest.java
@@ -7,10 +7,12 @@
import static com.android.tools.r8.apimodel.ApiModelingTestHelper.setMockApiLevelForClass;
import static com.android.tools.r8.apimodel.ApiModelingTestHelper.setMockApiLevelForDefaultInstanceInitializer;
import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.Assume.assumeFalse;
import com.android.tools.r8.TestBase;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.TestParametersCollection;
+import com.android.tools.r8.ToolHelper.DexVm.Version;
import com.android.tools.r8.testing.AndroidBuildVersion;
import com.android.tools.r8.utils.AndroidApiLevel;
import com.android.tools.r8.utils.codeinspector.Matchers;
@@ -34,6 +36,9 @@
@Test
public void testR8() throws Exception {
+ // TODO(b/197078995): Make this work on 12.
+ assumeFalse(
+ parameters.isDexRuntime() && parameters.getDexRuntimeVersion().isEqualTo(Version.V12_0_0));
boolean isMockApiLevel =
parameters.isDexRuntime() && parameters.getApiLevel().isGreaterThanOrEqualTo(mockLevel);
testForR8(parameters.getBackend())
@@ -49,7 +54,7 @@
.applyIf(
parameters.isDexRuntime()
&& parameters.getRuntime().maxSupportedApiLevel().isGreaterThanOrEqualTo(mockLevel),
- b -> b.addRunClasspathClasses(LibraryClass.class))
+ b -> b.addBootClasspathClasses(LibraryClass.class))
.run(parameters.getRuntime(), Main.class)
.assertSuccessWithOutputLinesIf(isMockApiLevel, "LibraryClass::foo")
.assertSuccessWithOutputLinesIf(!isMockApiLevel, "Hello World")
diff --git a/src/test/java/com/android/tools/r8/apimodel/ApiModelMockInheritedClassTest.java b/src/test/java/com/android/tools/r8/apimodel/ApiModelMockInheritedClassTest.java
index ad7cfc8..46a9fe8 100644
--- a/src/test/java/com/android/tools/r8/apimodel/ApiModelMockInheritedClassTest.java
+++ b/src/test/java/com/android/tools/r8/apimodel/ApiModelMockInheritedClassTest.java
@@ -7,10 +7,12 @@
import static com.android.tools.r8.apimodel.ApiModelingTestHelper.setMockApiLevelForClass;
import static com.android.tools.r8.apimodel.ApiModelingTestHelper.setMockApiLevelForDefaultInstanceInitializer;
import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.Assume.assumeFalse;
import com.android.tools.r8.TestBase;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.TestParametersCollection;
+import com.android.tools.r8.ToolHelper.DexVm.Version;
import com.android.tools.r8.testing.AndroidBuildVersion;
import com.android.tools.r8.utils.AndroidApiLevel;
import com.android.tools.r8.utils.codeinspector.Matchers;
@@ -34,6 +36,9 @@
@Test
public void testR8() throws Exception {
+ // TODO(b/197078995): Make this work on 12.
+ assumeFalse(
+ parameters.isDexRuntime() && parameters.getDexRuntimeVersion().isEqualTo(Version.V12_0_0));
boolean isMockApiLevel =
parameters.isDexRuntime() && parameters.getApiLevel().isGreaterThanOrEqualTo(mockLevel);
testForR8(parameters.getBackend())
@@ -50,7 +55,7 @@
.applyIf(
parameters.isDexRuntime()
&& parameters.getRuntime().maxSupportedApiLevel().isGreaterThanOrEqualTo(mockLevel),
- b -> b.addRunClasspathClasses(LibraryClass.class))
+ b -> b.addBootClasspathClasses(LibraryClass.class))
.run(parameters.getRuntime(), Main.class)
.assertSuccessWithOutputLinesIf(isMockApiLevel, "ProgramClass::foo")
.assertSuccessWithOutputLinesIf(!isMockApiLevel, "Hello World")
diff --git a/src/test/java/com/android/tools/r8/apimodel/ApiModelMockMethodMissingClassTest.java b/src/test/java/com/android/tools/r8/apimodel/ApiModelMockMethodMissingClassTest.java
index 5203e98..6b91898 100644
--- a/src/test/java/com/android/tools/r8/apimodel/ApiModelMockMethodMissingClassTest.java
+++ b/src/test/java/com/android/tools/r8/apimodel/ApiModelMockMethodMissingClassTest.java
@@ -8,10 +8,12 @@
import static com.android.tools.r8.apimodel.ApiModelingTestHelper.setMockApiLevelForDefaultInstanceInitializer;
import static com.android.tools.r8.apimodel.ApiModelingTestHelper.setMockApiLevelForMethod;
import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.Assume.assumeFalse;
import com.android.tools.r8.TestBase;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.TestParametersCollection;
+import com.android.tools.r8.ToolHelper.DexVm.Version;
import com.android.tools.r8.testing.AndroidBuildVersion;
import com.android.tools.r8.utils.AndroidApiLevel;
import com.android.tools.r8.utils.codeinspector.Matchers;
@@ -37,6 +39,9 @@
@Test
public void testR8() throws Exception {
+ // TODO(b/197078995): Make this work on 12.
+ assumeFalse(
+ parameters.isDexRuntime() && parameters.getDexRuntimeVersion().isEqualTo(Version.V12_0_0));
boolean preMockApis =
parameters.isCfRuntime() || parameters.getApiLevel().isLessThan(initialLibraryMockLevel);
boolean postMockApis =
@@ -64,7 +69,7 @@
.getRuntime()
.maxSupportedApiLevel()
.isGreaterThanOrEqualTo(initialLibraryMockLevel),
- b -> b.addRunClasspathClasses(LibraryClass.class))
+ b -> b.addBootClasspathClasses(LibraryClass.class))
.run(parameters.getRuntime(), Main.class)
.assertSuccessWithOutputLinesIf(preMockApis, "Hello World")
.assertSuccessWithOutputLinesIf(
diff --git a/src/test/java/com/android/tools/r8/apimodel/ApiModelMockSuperChainClassTest.java b/src/test/java/com/android/tools/r8/apimodel/ApiModelMockSuperChainClassTest.java
index 2d5df16..285f3d0 100644
--- a/src/test/java/com/android/tools/r8/apimodel/ApiModelMockSuperChainClassTest.java
+++ b/src/test/java/com/android/tools/r8/apimodel/ApiModelMockSuperChainClassTest.java
@@ -8,10 +8,12 @@
import static com.android.tools.r8.apimodel.ApiModelingTestHelper.setMockApiLevelForDefaultInstanceInitializer;
import static org.hamcrest.CoreMatchers.not;
import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.Assume.assumeFalse;
import com.android.tools.r8.TestBase;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.TestParametersCollection;
+import com.android.tools.r8.ToolHelper.DexVm.Version;
import com.android.tools.r8.testing.AndroidBuildVersion;
import com.android.tools.r8.utils.AndroidApiLevel;
import com.android.tools.r8.utils.codeinspector.Matchers;
@@ -36,6 +38,9 @@
@Test
public void testR8() throws Exception {
+ // TODO(b/197078995): Make this work on 12.
+ assumeFalse(
+ parameters.isDexRuntime() && parameters.getDexRuntimeVersion().isEqualTo(Version.V12_0_0));
boolean isMockApiLevel =
parameters.isDexRuntime() && parameters.getApiLevel().isGreaterThanOrEqualTo(mockApiLevel);
testForR8(parameters.getBackend())
@@ -58,14 +63,14 @@
.getRuntime()
.maxSupportedApiLevel()
.isGreaterThanOrEqualTo(lowerMockApiLevel),
- b -> b.addRunClasspathClasses(LibraryClass.class, LibraryInterface.class))
+ b -> b.addBootClasspathClasses(LibraryClass.class, LibraryInterface.class))
.applyIf(
parameters.isDexRuntime()
&& parameters
.getRuntime()
.maxSupportedApiLevel()
.isGreaterThanOrEqualTo(mockApiLevel),
- b -> b.addRunClasspathClasses(OtherLibraryClass.class))
+ b -> b.addBootClasspathClasses(OtherLibraryClass.class))
.run(parameters.getRuntime(), Main.class)
.assertSuccessWithOutputLinesIf(isMockApiLevel, "ProgramClass::foo")
.assertSuccessWithOutputLinesIf(!isMockApiLevel, "Hello World")