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);
   }