Test for use of main-dex-rules to bypass main-dex check.
Bug: b/241351268
Change-Id: I37c3f7001daf3976e6240cc261e3d4a3b8f3cba8
diff --git a/src/test/java/com/android/tools/r8/maindexlist/EmptyMainDexInputTest.java b/src/test/java/com/android/tools/r8/maindexlist/EmptyMainDexInputTest.java
new file mode 100644
index 0000000..c8fd985
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/maindexlist/EmptyMainDexInputTest.java
@@ -0,0 +1,70 @@
+// 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.
+package com.android.tools.r8.maindexlist;
+
+import static org.junit.Assert.assertEquals;
+
+import com.android.tools.r8.TestBase;
+import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.TestParametersCollection;
+import com.android.tools.r8.utils.AndroidApiLevel;
+import com.android.tools.r8.utils.IntBox;
+import com.android.tools.r8.utils.ZipUtils;
+import java.io.IOException;
+import java.nio.file.Path;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+
+@RunWith(Parameterized.class)
+public class EmptyMainDexInputTest extends TestBase {
+
+ @Parameterized.Parameters(name = "{0}")
+ public static TestParametersCollection data() {
+ return getTestParameters().withNoneRuntime().build();
+ }
+
+ public EmptyMainDexInputTest(TestParameters parameters) {
+ parameters.assertNoneRuntime();
+ }
+
+ @Test
+ public void testMainDexRulesAvoidsMainDexCheck() throws Exception {
+ Path app = temp.newFolder().toPath().resolve("app.jar");
+ MainDexListTests.generateManyClassesMultiDexApp(app);
+
+ Path debugOut =
+ testForD8(Backend.DEX)
+ .addProgramFiles(app)
+ .setMinApi(AndroidApiLevel.B)
+ .addMainDexRules("-keep class com.example.NotPresent")
+ .debug()
+ .compile()
+ .writeToZip();
+ checkOutputIsTwoFiles(debugOut);
+
+ Path releaseOut =
+ testForD8(Backend.DEX)
+ .addProgramFiles(app)
+ .setMinApi(AndroidApiLevel.B)
+ .addMainDexRules("-keep class com.example.NotPresent")
+ .release()
+ .compile()
+ .writeToZip();
+ checkOutputIsTwoFiles(releaseOut);
+ }
+
+ private void checkOutputIsTwoFiles(Path out) throws IOException {
+ // The example application fits in two files, check we don't have an empty "main-dex file".
+ IntBox classesFileCount = new IntBox(0);
+ ZipUtils.iter(
+ out,
+ (entry, input) -> {
+ if (entry.getName().startsWith("classes")) {
+ classesFileCount.increment();
+ }
+ });
+ assertEquals(2, classesFileCount.get());
+ }
+}
diff --git a/src/test/java/com/android/tools/r8/maindexlist/MainDexListTests.java b/src/test/java/com/android/tools/r8/maindexlist/MainDexListTests.java
index 25ffe36..8aeebd3 100644
--- a/src/test/java/com/android/tools/r8/maindexlist/MainDexListTests.java
+++ b/src/test/java/com/android/tools/r8/maindexlist/MainDexListTests.java
@@ -118,7 +118,7 @@
getManyClassesMultiDexAppPath(), MANY_CLASSES, MANY_CLASSES_MULTI_DEX_METHODS_PER_CLASS);
// Generates an application with two classes, each with the maximum possible number of methods.
- generateApplication(getTwoLargeClassesAppPath(), TWO_LARGE_CLASSES, getLargeClassMethodCount());
+ generateManyClassesMultiDexApp(getTwoLargeClassesAppPath());
}
private static int getLargeClassMethodCount() {
@@ -139,6 +139,10 @@
return generatedApplicationsFolder.getRoot().toPath().resolve("many-classes-stereo.zip");
}
+ public static void generateManyClassesMultiDexApp(Path path) throws IOException {
+ generateApplication(path, TWO_LARGE_CLASSES, getLargeClassMethodCount());
+ }
+
private static Set<DexType> parse(Path path, DexItemFactory itemFactory) {
return MainDexListParser.parseList(StringResource.fromFile(path), itemFactory);
}