Convert desugared library test

Finish conversiontests

Bug: b:231287675
Change-Id: Ib7c29b65484c7c6d19f5aa4c8cfaeb912d2f3501
diff --git a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/conversiontests/TryCatchTimeConversionTest.java b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/conversiontests/TryCatchTimeConversionTest.java
index aaab5cb..bd3d193 100644
--- a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/conversiontests/TryCatchTimeConversionTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/conversiontests/TryCatchTimeConversionTest.java
@@ -4,15 +4,18 @@
 
 package com.android.tools.r8.desugar.desugaredlibrary.conversiontests;
 
+import static com.android.tools.r8.desugar.desugaredlibrary.test.CompilationSpecification.DEFAULT_SPECIFICATIONS;
+import static com.android.tools.r8.desugar.desugaredlibrary.test.LibraryDesugaringSpecification.getJdk8Jdk11;
+
 import com.android.tools.r8.TestParameters;
 import com.android.tools.r8.desugar.desugaredlibrary.DesugaredLibraryTestBase;
+import com.android.tools.r8.desugar.desugaredlibrary.test.CompilationSpecification;
+import com.android.tools.r8.desugar.desugaredlibrary.test.CustomLibrarySpecification;
+import com.android.tools.r8.desugar.desugaredlibrary.test.LibraryDesugaringSpecification;
 import com.android.tools.r8.utils.AndroidApiLevel;
-import com.android.tools.r8.utils.BooleanUtils;
 import com.android.tools.r8.utils.StringUtils;
-import java.nio.file.Path;
 import java.time.ZoneId;
 import java.util.List;
-import org.junit.BeforeClass;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.junit.runners.Parameterized;
@@ -22,117 +25,53 @@
 public class TryCatchTimeConversionTest extends DesugaredLibraryTestBase {
 
   private final TestParameters parameters;
-  private final boolean shrinkDesugaredLibrary;
+  private final LibraryDesugaringSpecification libraryDesugaringSpecification;
+  private final CompilationSpecification compilationSpecification;
+
   private static final AndroidApiLevel MIN_SUPPORTED = AndroidApiLevel.O;
   private static final String EXPECTED_RESULT =
       StringUtils.lines("GMT", "GMT", "GMT", "GMT", "GMT");
   private static final String EXPECTED_RESULT_EXCEPTION =
       StringUtils.lines("GMT", "GMT", "GMT", "GMT", "GMT", "Exception caught");
-  private static Path CUSTOM_LIB;
 
-  @Parameters(name = "{0}, shrinkDesugaredLibrary: {1}")
+  @Parameters(name = "{0}, spec: {1}, {2}")
   public static List<Object[]> data() {
     return buildParameters(
-        getConversionParametersUpToExcluding(MIN_SUPPORTED), BooleanUtils.values());
+        getConversionParametersUpToExcluding(MIN_SUPPORTED),
+        getJdk8Jdk11(),
+        DEFAULT_SPECIFICATIONS);
   }
 
-  public TryCatchTimeConversionTest(TestParameters parameters, boolean shrinkDesugaredLibrary) {
-    this.shrinkDesugaredLibrary = shrinkDesugaredLibrary;
+  public TryCatchTimeConversionTest(
+      TestParameters parameters,
+      LibraryDesugaringSpecification libraryDesugaringSpecification,
+      CompilationSpecification compilationSpecification) {
     this.parameters = parameters;
-  }
-
-  @BeforeClass
-  public static void compileCustomLib() throws Exception {
-    CUSTOM_LIB =
-        testForD8(getStaticTemp())
-            .addProgramClasses(CustomLibClass.class)
-            .setMinApi(MIN_SUPPORTED)
-            .compile()
-            .writeToZip();
+    this.libraryDesugaringSpecification = libraryDesugaringSpecification;
+    this.compilationSpecification = compilationSpecification;
   }
 
   @Test
-  public void testBaselineD8() throws Exception {
-    KeepRuleConsumer keepRuleConsumer = createKeepRuleConsumer(parameters);
-    testForD8()
-        .setMinApi(parameters.getApiLevel())
+  public void testBaseline() throws Exception {
+    testForDesugaredLibrary(parameters, libraryDesugaringSpecification, compilationSpecification)
         .addProgramClasses(BaselineExecutor.class)
-        .addLibraryClasses(CustomLibClass.class)
-        .addLibraryFiles(getLibraryFile())
-        .enableCoreLibraryDesugaring(parameters.getApiLevel(), keepRuleConsumer)
-        .compile()
-        .addDesugaredCoreLibraryRunClassPath(
-            this::buildDesugaredLibrary,
-            parameters.getApiLevel(),
-            keepRuleConsumer.get(),
-            shrinkDesugaredLibrary)
-        .addRunClasspathFiles(CUSTOM_LIB)
-        .run(parameters.getRuntime(), BaselineExecutor.class)
-        .assertSuccessWithOutput(EXPECTED_RESULT);
-  }
-
-  @Test
-  public void testBaselineR8() throws Exception {
-    KeepRuleConsumer keepRuleConsumer = createKeepRuleConsumer(parameters);
-    testForR8(parameters.getBackend())
-        .addLibraryFiles(getLibraryFile())
-        .setMinApi(parameters.getApiLevel())
-        .addProgramClasses(BaselineExecutor.class)
+        .setCustomLibrarySpecification(
+            new CustomLibrarySpecification(CustomLibClass.class, MIN_SUPPORTED))
         .addKeepMainRule(BaselineExecutor.class)
-        .addLibraryClasses(CustomLibClass.class)
-        .enableCoreLibraryDesugaring(parameters.getApiLevel(), keepRuleConsumer)
-        .compile()
-        .addDesugaredCoreLibraryRunClassPath(
-            this::buildDesugaredLibrary,
-            parameters.getApiLevel(),
-            keepRuleConsumer.get(),
-            shrinkDesugaredLibrary)
-        .addRunClasspathFiles(CUSTOM_LIB)
         .run(parameters.getRuntime(), BaselineExecutor.class)
         .assertSuccessWithOutput(EXPECTED_RESULT);
   }
 
   @Test
-  public void testTryCatchD8() throws Exception {
-    KeepRuleConsumer keepRuleConsumer = createKeepRuleConsumer(parameters);
-    testForD8()
-        .setMinApi(parameters.getApiLevel())
+  public void testTryCatch() throws Exception {
+    testForDesugaredLibrary(parameters, libraryDesugaringSpecification, compilationSpecification)
         .addProgramClasses(TryCatchExecutor.class)
-        .addLibraryClasses(CustomLibClass.class)
-        .addLibraryFiles(getLibraryFile())
-        .enableCoreLibraryDesugaring(parameters.getApiLevel(), keepRuleConsumer)
-        .compile()
-        .addDesugaredCoreLibraryRunClassPath(
-            this::buildDesugaredLibrary,
-            parameters.getApiLevel(),
-            keepRuleConsumer.get(),
-            shrinkDesugaredLibrary)
-        .addRunClasspathFiles(CUSTOM_LIB)
-        .run(parameters.getRuntime(), TryCatchExecutor.class)
-        .assertSuccessWithOutput(EXPECTED_RESULT_EXCEPTION);
-  }
-
-  @Test
-  public void testTryCatchR8() throws Exception {
-    KeepRuleConsumer keepRuleConsumer = createKeepRuleConsumer(parameters);
-    testForR8(parameters.getBackend())
-        .addLibraryFiles(getLibraryFile())
-        .setMinApi(parameters.getApiLevel())
-        .addProgramClasses(TryCatchExecutor.class)
+        .setCustomLibrarySpecification(
+            new CustomLibrarySpecification(CustomLibClass.class, MIN_SUPPORTED))
         .addKeepMainRule(TryCatchExecutor.class)
-        .addLibraryClasses(CustomLibClass.class)
-        .enableCoreLibraryDesugaring(parameters.getApiLevel(), keepRuleConsumer)
-        .compile()
-        .addDesugaredCoreLibraryRunClassPath(
-            this::buildDesugaredLibrary,
-            parameters.getApiLevel(),
-            keepRuleConsumer.get(),
-            shrinkDesugaredLibrary)
-        .addRunClasspathFiles(CUSTOM_LIB)
         .run(parameters.getRuntime(), TryCatchExecutor.class)
         .assertSuccessWithOutput(EXPECTED_RESULT_EXCEPTION);
   }
-
   @SuppressWarnings("WeakerAccess")
   static class BaselineExecutor {
 
diff --git a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/conversiontests/UnwrapConversionTest.java b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/conversiontests/UnwrapConversionTest.java
index 888400d..278ec26 100644
--- a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/conversiontests/UnwrapConversionTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/conversiontests/UnwrapConversionTest.java
@@ -4,16 +4,19 @@
 
 package com.android.tools.r8.desugar.desugaredlibrary.conversiontests;
 
+import static com.android.tools.r8.desugar.desugaredlibrary.test.CompilationSpecification.DEFAULT_SPECIFICATIONS;
+import static com.android.tools.r8.desugar.desugaredlibrary.test.LibraryDesugaringSpecification.getJdk8Jdk11;
+
 import com.android.tools.r8.TestParameters;
 import com.android.tools.r8.desugar.desugaredlibrary.DesugaredLibraryTestBase;
+import com.android.tools.r8.desugar.desugaredlibrary.test.CompilationSpecification;
+import com.android.tools.r8.desugar.desugaredlibrary.test.CustomLibrarySpecification;
+import com.android.tools.r8.desugar.desugaredlibrary.test.LibraryDesugaringSpecification;
 import com.android.tools.r8.utils.AndroidApiLevel;
-import com.android.tools.r8.utils.BooleanUtils;
 import com.android.tools.r8.utils.StringUtils;
-import java.nio.file.Path;
 import java.util.List;
 import java.util.function.DoubleConsumer;
 import java.util.function.IntConsumer;
-import org.junit.BeforeClass;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.junit.runners.Parameterized;
@@ -23,69 +26,36 @@
 public class UnwrapConversionTest extends DesugaredLibraryTestBase {
 
   private final TestParameters parameters;
-  private final boolean shrinkDesugaredLibrary;
+  private final LibraryDesugaringSpecification libraryDesugaringSpecification;
+  private final CompilationSpecification compilationSpecification;
+
   private static final AndroidApiLevel MIN_SUPPORTED = AndroidApiLevel.N;
   private static final String EXPECTED_RESULT = StringUtils.lines("true", "true");
-  private static Path CUSTOM_LIB;
 
-  @Parameters(name = "{0}, shrinkDesugaredLibrary: {1}")
+  @Parameters(name = "{0}, spec: {1}, {2}")
   public static List<Object[]> data() {
     return buildParameters(
-        getConversionParametersUpToExcluding(MIN_SUPPORTED), BooleanUtils.values());
+        getConversionParametersUpToExcluding(MIN_SUPPORTED),
+        getJdk8Jdk11(),
+        DEFAULT_SPECIFICATIONS);
   }
 
-  public UnwrapConversionTest(TestParameters parameters, boolean shrinkDesugaredLibrary) {
-    this.shrinkDesugaredLibrary = shrinkDesugaredLibrary;
+  public UnwrapConversionTest(
+      TestParameters parameters,
+      LibraryDesugaringSpecification libraryDesugaringSpecification,
+      CompilationSpecification compilationSpecification) {
     this.parameters = parameters;
-  }
-
-  @BeforeClass
-  public static void compileCustomLib() throws Exception {
-    CUSTOM_LIB =
-        testForD8(getStaticTemp())
-            .addProgramClasses(CustomLibClass.class)
-            .setMinApi(MIN_SUPPORTED)
-            .compile()
-            .writeToZip();
+    this.libraryDesugaringSpecification = libraryDesugaringSpecification;
+    this.compilationSpecification = compilationSpecification;
   }
 
   @Test
-  public void testUnwrapD8() throws Exception {
-    KeepRuleConsumer keepRuleConsumer = createKeepRuleConsumer(parameters);
-    testForD8()
-        .addLibraryFiles(getLibraryFile())
-        .setMinApi(parameters.getApiLevel())
-        .addProgramClasses(Executor.class)
-        .addLibraryClasses(CustomLibClass.class)
-        .enableCoreLibraryDesugaring(parameters.getApiLevel(), keepRuleConsumer)
-        .compile()
-        .addDesugaredCoreLibraryRunClassPath(
-            this::buildDesugaredLibrary,
-            parameters.getApiLevel(),
-            keepRuleConsumer.get(),
-            shrinkDesugaredLibrary)
-        .addRunClasspathFiles(CUSTOM_LIB)
-        .run(parameters.getRuntime(), Executor.class)
-        .assertSuccessWithOutput(EXPECTED_RESULT);
-  }
-
-  @Test
-  public void testUnwrapR8() throws Exception {
-    KeepRuleConsumer keepRuleConsumer = createKeepRuleConsumer(parameters);
-    testForR8(parameters.getBackend())
-        .addLibraryFiles(getLibraryFile())
-        .setMinApi(parameters.getApiLevel())
+  public void testUnwrap() throws Exception {
+    testForDesugaredLibrary(parameters, libraryDesugaringSpecification, compilationSpecification)
         .addProgramClasses(Executor.class)
         .addKeepMainRule(Executor.class)
-        .addLibraryClasses(CustomLibClass.class)
-        .enableCoreLibraryDesugaring(parameters.getApiLevel(), keepRuleConsumer)
-        .compile()
-        .addDesugaredCoreLibraryRunClassPath(
-            this::buildDesugaredLibrary,
-            parameters.getApiLevel(),
-            keepRuleConsumer.get(),
-            shrinkDesugaredLibrary)
-        .addRunClasspathFiles(CUSTOM_LIB)
+        .setCustomLibrarySpecification(
+            new CustomLibrarySpecification(CustomLibClass.class, MIN_SUPPORTED))
         .run(parameters.getRuntime(), Executor.class)
         .assertSuccessWithOutput(EXPECTED_RESULT);
   }
diff --git a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/conversiontests/WrapperPlacementTest.java b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/conversiontests/WrapperPlacementTest.java
index bda8534..424009b 100644
--- a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/conversiontests/WrapperPlacementTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/conversiontests/WrapperPlacementTest.java
@@ -4,24 +4,29 @@
 
 package com.android.tools.r8.desugar.desugaredlibrary.conversiontests;
 
+import static com.android.tools.r8.desugar.desugaredlibrary.test.CompilationSpecification.D8_L8DEBUG;
+import static com.android.tools.r8.desugar.desugaredlibrary.test.LibraryDesugaringSpecification.JDK8;
+import static com.android.tools.r8.desugar.desugaredlibrary.test.LibraryDesugaringSpecification.getJdk8Jdk11;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotEquals;
 import static org.junit.Assume.assumeTrue;
 
-import com.android.tools.r8.LibraryDesugaringTestConfiguration;
 import com.android.tools.r8.TestParameters;
-import com.android.tools.r8.TestParametersCollection;
 import com.android.tools.r8.desugar.desugaredlibrary.DesugaredLibraryTestBase;
+import com.android.tools.r8.desugar.desugaredlibrary.test.CompilationSpecification;
+import com.android.tools.r8.desugar.desugaredlibrary.test.LibraryDesugaringSpecification;
 import com.android.tools.r8.synthesis.SyntheticItemsTestUtils;
 import com.android.tools.r8.testing.AndroidBuildVersion;
 import com.android.tools.r8.utils.AndroidApiLevel;
 import com.android.tools.r8.utils.StringUtils;
 import com.android.tools.r8.utils.codeinspector.CodeInspector;
 import com.android.tools.r8.utils.codeinspector.FoundClassSubject;
-import java.io.IOException;
+import com.google.common.collect.ImmutableList;
 import java.nio.file.Path;
 import java.util.Arrays;
+import java.util.List;
 import java.util.stream.Stream;
+import org.junit.Assume;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.junit.runners.Parameterized;
@@ -30,22 +35,36 @@
 @RunWith(Parameterized.class)
 public class WrapperPlacementTest extends DesugaredLibraryTestBase {
 
+  private final TestParameters parameters;
+  private final LibraryDesugaringSpecification libraryDesugaringSpecification;
+  private final CompilationSpecification compilationSpecification;
+
   private static final String EXPECTED = StringUtils.lines("[1, 2, 3]", "[2, 3, 4]");
 
-  @Parameters(name = "{0}")
-  public static TestParametersCollection data() {
-    return getTestParameters().withAllRuntimesAndApiLevels().build();
+  @Parameters(name = "{0}, spec: {1}, {2}")
+  public static List<Object[]> data() {
+    return buildParameters(
+        getTestParameters().withAllRuntimesAndApiLevels().build(),
+        getJdk8Jdk11(),
+        ImmutableList.of(D8_L8DEBUG));
   }
 
-  private final TestParameters parameters;
-
-  public WrapperPlacementTest(TestParameters parameters) {
+  public WrapperPlacementTest(
+      TestParameters parameters,
+      LibraryDesugaringSpecification libraryDesugaringSpecification,
+      CompilationSpecification compilationSpecification) {
     this.parameters = parameters;
+    this.libraryDesugaringSpecification = libraryDesugaringSpecification;
+    this.compilationSpecification = compilationSpecification;
   }
 
   @Test
   public void testReference() throws Exception {
-    assumeTrue(parameters.isCfRuntime());
+    Assume.assumeTrue(
+        "No need to test twice",
+        parameters.isCfRuntime()
+            && libraryDesugaringSpecification == JDK8
+            && compilationSpecification.isProgramShrink());
     testForJvm()
         .addAndroidBuildVersion()
         .addProgramClassesAndInnerClasses(MyArrays1.class)
@@ -56,44 +75,27 @@
   }
 
   @Test
-  public void testNoWrappers() throws Exception {
+  public void testNoWrappers() throws Throwable {
     assumeTrue(parameters.isDexRuntime());
     // No wrappers are made during program compilation.
     Path path1 = compileWithCoreLibraryDesugaring(MyArrays1.class);
     Path path2 = compileWithCoreLibraryDesugaring(MyArrays2.class);
-    testForD8()
-        .addLibraryFiles(getLibraryFile())
+
+    testForDesugaredLibrary(parameters, libraryDesugaringSpecification, compilationSpecification)
         .addProgramClasses(TestClass.class)
         .addAndroidBuildVersion()
-        .enableCoreLibraryDesugaring(
-            LibraryDesugaringTestConfiguration.builder()
-                .setMinApi(parameters.getApiLevel())
-                .dontAddRunClasspath()
-                .build())
-        .setMinApi(parameters.getApiLevel())
         .compile()
         .inspect(this::assertNoWrappers)
-        .apply(
-            b -> {
-              if (!hasNativeIntUnaryOperator()) {
-                Path coreLib = buildDesugaredLibrary(parameters.getApiLevel());
-                assertCoreLibContainsWrappers(coreLib);
-                b.addRunClasspathFiles(coreLib);
-              }
-            })
-        // The previous compilations are appended to the classpath (no merge).
+        .inspectL8(this::assertCoreLibContainsWrappers)
         .addRunClasspathFiles(path1, path2)
         .run(parameters.getRuntime(), TestClass.class)
         .assertSuccessWithOutput(EXPECTED);
   }
 
-  private Path compileWithCoreLibraryDesugaring(Class<?> clazz) throws Exception {
-    return testForD8()
-        .addLibraryFiles(getLibraryFile())
+  private Path compileWithCoreLibraryDesugaring(Class<?> clazz) throws Throwable {
+    return testForDesugaredLibrary(
+            parameters, libraryDesugaringSpecification, compilationSpecification)
         .addProgramClassesAndInnerClasses(clazz)
-        .setMinApi(parameters.getApiLevel())
-        .enableCoreLibraryDesugaring(
-            LibraryDesugaringTestConfiguration.forApiLevel(parameters.getApiLevel()))
         .compile()
         .inspect(this::assertNoWrappers)
         .writeToZip();
@@ -103,10 +105,11 @@
     return parameters.getApiLevel().isGreaterThanOrEqualTo(AndroidApiLevel.N);
   }
 
-  private void assertCoreLibContainsWrappers(Path coreLib) throws IOException {
-    CodeInspector inspector = new CodeInspector(coreLib);
-    Stream<FoundClassSubject> wrappers = getWrappers(inspector);
-    assertNotEquals(0, wrappers.count());
+  private void assertCoreLibContainsWrappers(CodeInspector inspector) {
+    if (!hasNativeIntUnaryOperator()) {
+      Stream<FoundClassSubject> wrappers = getWrappers(inspector);
+      assertNotEquals(0, wrappers.count());
+    }
   }
 
   private void assertNoWrappers(CodeInspector inspector) {
diff --git a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/test/DesugaredLibraryTestBuilder.java b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/test/DesugaredLibraryTestBuilder.java
index 089b9b3..ac3ed05 100644
--- a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/test/DesugaredLibraryTestBuilder.java
+++ b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/test/DesugaredLibraryTestBuilder.java
@@ -23,7 +23,6 @@
 import com.android.tools.r8.utils.InternalOptions;
 import java.io.IOException;
 import java.nio.file.Path;
-import java.util.concurrent.ExecutionException;
 import java.util.function.Consumer;
 import org.junit.Assume;
 
@@ -101,6 +100,12 @@
     return this;
   }
 
+  public DesugaredLibraryTestBuilder<T> addProgramClassesAndInnerClasses(Class<?>... clazz)
+      throws IOException {
+    builder.addProgramClassesAndInnerClasses(clazz);
+    return this;
+  }
+
   public DesugaredLibraryTestBuilder<T> addInnerClasses(Class<?>... clazz) throws IOException {
     builder.addInnerClasses(clazz);
     return this;
@@ -155,7 +160,7 @@
   }
 
   private D8TestCompileResult compileCustomLib() throws CompilationFailedException {
-    if (compilationSpecification == null) {
+    if (customLibrarySpecification == null) {
       return null;
     }
     return test.testForD8()
@@ -164,8 +169,7 @@
         .compile();
   }
 
-  private L8TestCompileResult compileDesugaredLibrary(String keepRule)
-      throws IOException, CompilationFailedException, ExecutionException {
+  private L8TestCompileResult compileDesugaredLibrary(String keepRule) throws Exception {
     return test.testForL8(parameters.getApiLevel(), parameters.getBackend())
         .addProgramFiles(libraryDesugaringSpecification.getDesugarJdkLibs())
         .addLibraryFiles(libraryDesugaringSpecification.getAndroidJar())
@@ -214,4 +218,9 @@
                 builder ->
                     builder.setSupportAllCallbacksFromLibrary(supportAllCallbacksFromLibrary)));
   }
+
+  public DesugaredLibraryTestBuilder<T> addAndroidBuildVersion() {
+    builder.addAndroidBuildVersion();
+    return this;
+  }
 }
diff --git a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/test/DesugaredLibraryTestCompileResult.java b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/test/DesugaredLibraryTestCompileResult.java
index 78b9fb1..07458ab 100644
--- a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/test/DesugaredLibraryTestCompileResult.java
+++ b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/test/DesugaredLibraryTestCompileResult.java
@@ -14,7 +14,11 @@
 import com.android.tools.r8.desugar.desugaredlibrary.DesugaredLibraryTestBase;
 import com.android.tools.r8.utils.ThrowingConsumer;
 import com.android.tools.r8.utils.codeinspector.CodeInspector;
+import java.io.IOException;
 import java.nio.file.Path;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
 import java.util.function.Consumer;
 
 public class DesugaredLibraryTestCompileResult<T extends DesugaredLibraryTestBase> {
@@ -26,6 +30,7 @@
   private final CompilationSpecification compilationSpecification;
   private final D8TestCompileResult customLibCompile;
   private final L8TestCompileResult l8Compile;
+  private final List<Path> runClasspathFiles = new ArrayList<>();
 
   public DesugaredLibraryTestCompileResult(
       T test,
@@ -110,7 +115,9 @@
       actualCompileResult.addRunClasspathFiles(customLibCompile.writeToZip());
     }
 
-    actualCompileResult.addRunClasspathFiles(desugaredLibrary);
+    actualCompileResult
+        .addRunClasspathFiles(desugaredLibrary)
+        .addRunClasspathFiles(runClasspathFiles);
 
     return actualCompileResult.run(runtime, mainClassName, args);
   }
@@ -122,4 +129,13 @@
         .disableDesugaring()
         .compile();
   }
+
+  public Path writeToZip() throws IOException {
+    return compileResult.writeToZip();
+  }
+
+  public DesugaredLibraryTestCompileResult<T> addRunClasspathFiles(Path... classpathFiles) {
+    Collections.addAll(runClasspathFiles, classpathFiles);
+    return this;
+  }
 }