Add a sanity check test for processkeepruleslib.jar
Change-Id: Ibfd7e7072216c149b528015027ba5f91f0f99c9c
diff --git a/d8_r8/commonBuildSrc/src/main/kotlin/TestConfigurationHelper.kt b/d8_r8/commonBuildSrc/src/main/kotlin/TestConfigurationHelper.kt
index 6b5f2a1..a1844cc 100644
--- a/d8_r8/commonBuildSrc/src/main/kotlin/TestConfigurationHelper.kt
+++ b/d8_r8/commonBuildSrc/src/main/kotlin/TestConfigurationHelper.kt
@@ -113,9 +113,15 @@
if (project.hasProperty("no_internal")) {
test.exclude("com/android/tools/r8/internal/**")
}
+
+ // Include sanity checks on lib jars when running --only_internal.
if (project.hasProperty("only_internal")) {
test.include("com/android/tools/r8/internal/**")
+ test.include("com/android/tools/r8/processkeeprules/sanitychecks/**")
+ } else {
+ test.exclude("com/android/tools/r8/processkeeprules/sanitychecks/**")
}
+
if (project.hasProperty("no_arttests")) {
test.exclude("com/android/tools/r8/art/**")
}
diff --git a/d8_r8/test/build.gradle.kts b/d8_r8/test/build.gradle.kts
index c82208b..0e7392d 100644
--- a/d8_r8/test/build.gradle.kts
+++ b/d8_r8/test/build.gradle.kts
@@ -27,6 +27,7 @@
val assistantJarTask = projectTask("assistant", "jar")
val mainDepsJarTask = projectTask("main", "depsJar")
val swissArmyKnifeTask = projectTask("main", "swissArmyKnife")
+val processKeepRulesLibWithRelocatedDepsTask = projectTask("main", "processKeepRulesLibWithRelocatedDeps")
val r8WithRelocatedDepsTask = projectTask("main", "r8WithRelocatedDeps")
val mainSourcesTask = projectTask("main", "sourcesJar")
val resourceShrinkerSourcesTask = projectTask("resourceshrinker", "sourcesJar")
@@ -500,6 +501,10 @@
dependsOn(gradle.includedBuild("shared").task(":downloadDepsInternal"))
dependsOn(gradle.includedBuild("shared").task(":downloadTestDepsInternal"))
}
+ // Build processkeepruleslib.jar when running with --only_internal.
+ if (project.hasProperty("only_internal")) {
+ dependsOn(processKeepRulesLibWithRelocatedDepsTask)
+ }
if (project.hasProperty("r8lib")) {
dependsOn(testR8LibWithRelocatedDeps)
} else if (project.hasProperty("r8lib_no_deps")) {
diff --git a/src/test/java/com/android/tools/r8/processkeeprules/sanitychecks/ProcessKeepRulesSanityCheckTest.java b/src/test/java/com/android/tools/r8/processkeeprules/sanitychecks/ProcessKeepRulesSanityCheckTest.java
new file mode 100644
index 0000000..91217ca
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/processkeeprules/sanitychecks/ProcessKeepRulesSanityCheckTest.java
@@ -0,0 +1,90 @@
+// Copyright (c) 2025, 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.
+package com.android.tools.r8.processkeeprules.sanitychecks;
+
+import static com.android.tools.r8.ToolHelper.PROCESS_KEEP_RULES_JAR;
+import static com.android.tools.r8.ToolHelper.PROCESS_KEEP_RULES_MAP;
+import static org.hamcrest.CoreMatchers.startsWith;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import com.android.tools.r8.TestBase;
+import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.TestParametersCollection;
+import com.android.tools.r8.Version;
+import com.android.tools.r8.utils.BooleanBox;
+import com.android.tools.r8.utils.FileUtils;
+import com.android.tools.r8.utils.StreamUtils;
+import com.android.tools.r8.utils.ZipUtils;
+import java.nio.file.Files;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameter;
+import org.junit.runners.Parameterized.Parameters;
+
+/**
+ * This test relies on build/libs/processkeepruleslib.jar being built. This test therefore only runs
+ * when test.py is run with the --only_internal flag, which adds a dependency on
+ * :main:processKeepRulesLibWithRelocatedDeps.
+ */
+@RunWith(Parameterized.class)
+public class ProcessKeepRulesSanityCheckTest extends TestBase {
+
+ @Parameter(0)
+ public TestParameters parameters;
+
+ @Parameters(name = "{0}")
+ public static TestParametersCollection data() {
+ return getTestParameters().withNoneRuntime().build();
+ }
+
+ @Test
+ public void testProcessKeepRulesJarContent() throws Exception {
+ assertTrue(Files.exists(PROCESS_KEEP_RULES_JAR));
+ assertTrue(Files.exists(PROCESS_KEEP_RULES_MAP));
+ BooleanBox apiDatabaseSeen = new BooleanBox();
+ BooleanBox licenseSeen = new BooleanBox();
+ BooleanBox manifestSeen = new BooleanBox();
+ BooleanBox versionSeen = new BooleanBox();
+ ZipUtils.iter(
+ PROCESS_KEEP_RULES_JAR,
+ (entry, input) -> {
+ String name = entry.getName();
+ if (ZipUtils.isClassFile(name) || FileUtils.isKotlinBuiltinsFile(name)) {
+ assertThat(name, startsWith("com/android/tools/r8/"));
+ if (ZipUtils.isClassFile(name)) {
+ byte[] classFileBytes = StreamUtils.streamToByteArrayClose(input);
+ String sourceFile = extractSourceFile(classFileBytes);
+ assertNotNull(sourceFile);
+ if (Version.isMainVersion()) {
+ assertTrue(sourceFile, sourceFile.startsWith("R8_"));
+ assertEquals(108, sourceFile.length());
+ } else {
+ assertTrue(sourceFile, sourceFile.startsWith("R8_" + Version.LABEL));
+ assertEquals(68 + Version.LABEL.length(), sourceFile.length());
+ }
+ versionSeen.or(name.equals("com/android/tools/r8/Version.class"));
+ }
+ } else if (name.equals("META-INF/MANIFEST.MF")) {
+ manifestSeen.set();
+ } else if (name.equals("LICENSE")) {
+ licenseSeen.set();
+ } else if (name.equals("resources/new_api_database.ser")) {
+ apiDatabaseSeen.set();
+ } else if (name.endsWith("/")) {
+ fail("Unexpected directory entry '" + name + "'");
+ } else {
+ fail("Unexpected entry '" + name + "'");
+ }
+ });
+ assertTrue("Api database entry FOUND", apiDatabaseSeen.isFalse());
+ assertTrue("LICENSE entry NOT FOUND", licenseSeen.isTrue());
+ assertTrue("META-INF/MANIFEST.MF entry NOT FOUND", manifestSeen.isTrue());
+ assertTrue("com/android/tools/r8/Version.class entry NOT FOUND", versionSeen.isTrue());
+ }
+}
diff --git a/src/test/testbase/java/com/android/tools/r8/ToolHelper.java b/src/test/testbase/java/com/android/tools/r8/ToolHelper.java
index 59ca961..086e9b5 100644
--- a/src/test/testbase/java/com/android/tools/r8/ToolHelper.java
+++ b/src/test/testbase/java/com/android/tools/r8/ToolHelper.java
@@ -264,6 +264,9 @@
public static final Path R8_WITH_RELOCATED_DEPS_17_JAR =
Paths.get(LIBS_DIR, "r8_with_relocated_deps_17.jar");
public static final Path ASSISTANT_JAR = Paths.get(LIBS_DIR, "assistant.jar");
+ public static final Path PROCESS_KEEP_RULES_JAR = Paths.get(LIBS_DIR, "processkeepruleslib.jar");
+ public static final Path PROCESS_KEEP_RULES_MAP =
+ Paths.get(LIBS_DIR, "processkeepruleslib.jar.map");
public static final Path R8LIB_JAR = Paths.get(LIBS_DIR, "r8lib.jar");
public static final Path R8LIB_MAP = Paths.get(LIBS_DIR, "r8lib.jar.map");
public static final Path R8LIB_MAP_PARTITIONED = Paths.get(LIBS_DIR, "r8lib.jar_map.zip");