More desugared library tests

- API for keep rule generation in tests
- Function not supported on recent API levels

Bug: 134732760
Change-Id: Id46305f9382eace0e9d9b89b69a45232a09eefe4
diff --git a/src/test/java/com/android/tools/r8/D8TestBuilder.java b/src/test/java/com/android/tools/r8/D8TestBuilder.java
index e3db7cc..7b53857 100644
--- a/src/test/java/com/android/tools/r8/D8TestBuilder.java
+++ b/src/test/java/com/android/tools/r8/D8TestBuilder.java
@@ -55,7 +55,7 @@
       Builder builder, Consumer<InternalOptions> optionsConsumer, Supplier<AndroidApp> app)
       throws CompilationFailedException {
     ToolHelper.runD8(builder, optionsConsumer);
-    return new D8TestCompileResult(getState(), app.get(), getOutputMode());
+    return new D8TestCompileResult(getState(), app.get(), getOutputMode(), keepRulesHolder);
   }
 
   public D8TestBuilder setIntermediate(boolean intermediate) {
diff --git a/src/test/java/com/android/tools/r8/D8TestCompileResult.java b/src/test/java/com/android/tools/r8/D8TestCompileResult.java
index e4ea07c..02ce637 100644
--- a/src/test/java/com/android/tools/r8/D8TestCompileResult.java
+++ b/src/test/java/com/android/tools/r8/D8TestCompileResult.java
@@ -6,10 +6,13 @@
 import com.android.tools.r8.TestBase.Backend;
 import com.android.tools.r8.ToolHelper.ProcessResult;
 import com.android.tools.r8.utils.AndroidApp;
+import com.android.tools.r8.utils.Box;
 
 public class D8TestCompileResult extends TestCompileResult<D8TestCompileResult, D8TestRunResult> {
-  D8TestCompileResult(TestState state, AndroidApp app, OutputMode outputMode) {
-    super(state, app, outputMode);
+
+  D8TestCompileResult(
+      TestState state, AndroidApp app, OutputMode outputMode, Box<String> keepRulesHolder) {
+    super(state, app, outputMode, keepRulesHolder);
     assert ToolHelper.verifyValidOutputMode(Backend.DEX, outputMode);
   }
 
diff --git a/src/test/java/com/android/tools/r8/R8TestBuilder.java b/src/test/java/com/android/tools/r8/R8TestBuilder.java
index d6d3f5d..5ab864b 100644
--- a/src/test/java/com/android/tools/r8/R8TestBuilder.java
+++ b/src/test/java/com/android/tools/r8/R8TestBuilder.java
@@ -98,7 +98,8 @@
         box.proguardConfiguration,
         box.syntheticProguardRules,
         proguardMapBuilder.toString(),
-        graphConsumer);
+        graphConsumer,
+        null);
   }
 
   public Builder getBuilder() {
diff --git a/src/test/java/com/android/tools/r8/R8TestCompileResult.java b/src/test/java/com/android/tools/r8/R8TestCompileResult.java
index 8e63f34..325046b 100644
--- a/src/test/java/com/android/tools/r8/R8TestCompileResult.java
+++ b/src/test/java/com/android/tools/r8/R8TestCompileResult.java
@@ -8,6 +8,7 @@
 import com.android.tools.r8.shaking.ProguardConfiguration;
 import com.android.tools.r8.shaking.ProguardConfigurationRule;
 import com.android.tools.r8.utils.AndroidApp;
+import com.android.tools.r8.utils.Box;
 import com.android.tools.r8.utils.codeinspector.CodeInspector;
 import com.android.tools.r8.utils.graphinspector.GraphInspector;
 import java.io.IOException;
@@ -29,8 +30,9 @@
       ProguardConfiguration proguardConfiguration,
       List<ProguardConfigurationRule> syntheticProguardRules,
       String proguardMap,
-      CollectingGraphConsumer graphConsumer) {
-    super(state, app, outputMode);
+      CollectingGraphConsumer graphConsumer,
+      Box<String> keepRulesHolder) {
+    super(state, app, outputMode, keepRulesHolder);
     this.proguardConfiguration = proguardConfiguration;
     this.syntheticProguardRules = syntheticProguardRules;
     this.proguardMap = proguardMap;
diff --git a/src/test/java/com/android/tools/r8/TestCompileResult.java b/src/test/java/com/android/tools/r8/TestCompileResult.java
index 31cdf50..eb2ccc4 100644
--- a/src/test/java/com/android/tools/r8/TestCompileResult.java
+++ b/src/test/java/com/android/tools/r8/TestCompileResult.java
@@ -18,6 +18,7 @@
 import com.android.tools.r8.errors.Unreachable;
 import com.android.tools.r8.utils.AndroidApiLevel;
 import com.android.tools.r8.utils.AndroidApp;
+import com.android.tools.r8.utils.Box;
 import com.android.tools.r8.utils.DescriptorUtils;
 import com.android.tools.r8.utils.TriFunction;
 import com.android.tools.r8.utils.codeinspector.ClassSubject;
@@ -47,11 +48,18 @@
   final List<String> vmArguments = new ArrayList<>();
   private boolean withArt6Plus64BitsLib = false;
   private boolean withArtFrameworks = true;
+  private final String desugaredLibraryKeepRules;
 
   TestCompileResult(TestState state, AndroidApp app, OutputMode outputMode) {
+    this(state, app, outputMode, null);
+  }
+
+  TestCompileResult(
+      TestState state, AndroidApp app, OutputMode outputMode, Box<String> keepRulesHolder) {
     super(state);
     this.app = app;
     this.outputMode = outputMode;
+    this.desugaredLibraryKeepRules = keepRulesHolder == null ? null : keepRulesHolder.get();
   }
 
   public final CR withArt6Plus64BitsLib() {
@@ -64,6 +72,10 @@
     return self();
   }
 
+  public String getDesugaredLibraryKeepRules() {
+    return desugaredLibraryKeepRules;
+  }
+
   public final Backend getBackend() {
     if (outputMode == OutputMode.ClassFile) {
       return Backend.CF;
@@ -176,10 +188,9 @@
   public CR addDesugaredCoreLibraryRunClassPath(
       TriFunction<AndroidApiLevel, String, Boolean, Path> classPathSupplier,
       AndroidApiLevel minAPILevel,
-      String keepRules,
       boolean shrink) {
     if (minAPILevel.getLevel() < AndroidApiLevel.O.getLevel()) {
-      addRunClasspathFiles(classPathSupplier.apply(minAPILevel, keepRules, shrink));
+      addRunClasspathFiles(classPathSupplier.apply(minAPILevel, desugaredLibraryKeepRules, shrink));
     }
     return self();
   }
diff --git a/src/test/java/com/android/tools/r8/TestCompilerBuilder.java b/src/test/java/com/android/tools/r8/TestCompilerBuilder.java
index 8498704..c63c4c7 100644
--- a/src/test/java/com/android/tools/r8/TestCompilerBuilder.java
+++ b/src/test/java/com/android/tools/r8/TestCompilerBuilder.java
@@ -8,6 +8,7 @@
 import com.android.tools.r8.utils.AndroidApiLevel;
 import com.android.tools.r8.utils.AndroidApp;
 import com.android.tools.r8.utils.AndroidAppConsumers;
+import com.android.tools.r8.utils.Box;
 import com.android.tools.r8.utils.InternalOptions;
 import com.google.common.base.Suppliers;
 import java.io.IOException;
@@ -43,6 +44,7 @@
   private Consumer<InternalOptions> optionsConsumer = DEFAULT_OPTIONS;
   private PrintStream stdout = null;
   protected OutputMode outputMode = OutputMode.DexIndexed;
+  protected Box<String> keepRulesHolder;
 
   TestCompilerBuilder(TestState state, B builder, Backend backend) {
     super(state, builder);
@@ -276,6 +278,11 @@
     if (minAPILevel.getLevel() < AndroidApiLevel.O.getLevel()) {
       builder.addLibraryFiles(ToolHelper.getAndroidJar(AndroidApiLevel.O));
       builder.addSpecialLibraryConfiguration("default");
+      keepRulesHolder = new Box<>("");
+      this.addOptionsModification(
+          options ->
+              options.testing.desugaredLibraryKeepRuleConsumer =
+                  (string, handler) -> this.keepRulesHolder.set(keepRulesHolder.get() + string));
     }
     return self();
   }
diff --git a/src/test/java/com/android/tools/r8/desugar/corelib/CustomCollectionTest.java b/src/test/java/com/android/tools/r8/desugar/corelib/CustomCollectionTest.java
index 099c560..678a395 100644
--- a/src/test/java/com/android/tools/r8/desugar/corelib/CustomCollectionTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/corelib/CustomCollectionTest.java
@@ -48,22 +48,16 @@
 
   @Test
   public void testCustomCollectionD8() throws Exception {
-    Box<String> keepRulesHolder = new Box<>("");
     D8TestRunResult d8TestRunResult =
         testForD8()
             .addInnerClasses(CustomCollectionTest.class)
             .setMinApi(parameters.getApiLevel())
-            .addOptionsModification(
-                options ->
-                    options.testing.desugaredLibraryKeepRuleConsumer =
-                        (string, handler) -> keepRulesHolder.set(keepRulesHolder.get() + string))
             .enableCoreLibraryDesugaring(parameters.getApiLevel())
             .compile()
             .inspect(inspector -> this.assertCustomCollectionCallsCorrect(inspector, false))
             .addDesugaredCoreLibraryRunClassPath(
                 this::buildDesugaredLibrary,
                 parameters.getApiLevel(),
-                keepRulesHolder.get(),
                 shrinkCoreLibrary)
             .run(parameters.getRuntime(), EXECUTOR)
             .assertSuccess();
@@ -82,23 +76,17 @@
 
   @Test
   public void testCustomCollectionR8() throws Exception {
-    Box<String> keepRulesHolder = new Box<>("");
     R8TestRunResult r8TestRunResult =
         testForR8(Backend.DEX)
             .addInnerClasses(CustomCollectionTest.class)
             .setMinApi(parameters.getApiLevel())
             .addKeepClassAndMembersRules(Executor.class)
-            .addOptionsModification(
-                options ->
-                    options.testing.desugaredLibraryKeepRuleConsumer =
-                        (string, handler) -> keepRulesHolder.set(keepRulesHolder.get() + string))
             .enableCoreLibraryDesugaring(parameters.getApiLevel())
             .compile()
             .inspect(inspector -> this.assertCustomCollectionCallsCorrect(inspector, true))
             .addDesugaredCoreLibraryRunClassPath(
                 this::buildDesugaredLibrary,
                 parameters.getApiLevel(),
-                keepRulesHolder.get(),
                 shrinkCoreLibrary)
             .run(parameters.getRuntime(), EXECUTOR)
             .assertSuccess();
diff --git a/src/test/java/com/android/tools/r8/desugar/corelib/JavaTimeTest.java b/src/test/java/com/android/tools/r8/desugar/corelib/JavaTimeTest.java
index fb1c722..b43523c 100644
--- a/src/test/java/com/android/tools/r8/desugar/corelib/JavaTimeTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/corelib/JavaTimeTest.java
@@ -55,21 +55,15 @@
 
   @Test
   public void testTimeD8() throws Exception {
-    Box<String> keepRulesHolder = new Box<>("");
     testForD8()
         .addInnerClasses(JavaTimeTest.class)
         .setMinApi(parameters.getApiLevel())
         .enableCoreLibraryDesugaring(parameters.getApiLevel())
-        .addOptionsModification(
-            options ->
-                options.testing.desugaredLibraryKeepRuleConsumer =
-                    (string, handler) -> keepRulesHolder.set(keepRulesHolder.get() + string))
         .compile()
         .inspect(this::checkRewrittenInvokes)
         .addDesugaredCoreLibraryRunClassPath(
             this::buildDesugaredLibrary,
             parameters.getApiLevel(),
-            keepRulesHolder.get(),
             shrinkCoreLibrary)
         .run(parameters.getRuntime(), TestClass.class)
         .assertSuccessWithOutput(expectedOutput);
@@ -77,22 +71,16 @@
 
   @Test
   public void testTimeR8() throws Exception {
-    Box<String> keepRulesHolder = new Box<>("");
     testForR8(parameters.getBackend())
         .addInnerClasses(JavaTimeTest.class)
         .addKeepMainRule(TestClass.class)
         .setMinApi(parameters.getApiLevel())
         .enableCoreLibraryDesugaring(parameters.getApiLevel())
-        .addOptionsModification(
-            options ->
-                options.testing.desugaredLibraryKeepRuleConsumer =
-                    (string, handler) -> keepRulesHolder.set(keepRulesHolder.get() + string))
         .compile()
         .inspect(this::checkRewrittenInvokes)
         .addDesugaredCoreLibraryRunClassPath(
             this::buildDesugaredLibrary,
             parameters.getApiLevel(),
-            keepRulesHolder.get(),
             shrinkCoreLibrary)
         .run(parameters.getRuntime(), TestClass.class)
         .assertSuccessWithOutput(expectedOutput);
diff --git a/src/test/java/com/android/tools/r8/desugar/corelib/JavaUtilFunctionTest.java b/src/test/java/com/android/tools/r8/desugar/corelib/JavaUtilFunctionTest.java
index 74a4efa..81c5c07 100644
--- a/src/test/java/com/android/tools/r8/desugar/corelib/JavaUtilFunctionTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/corelib/JavaUtilFunctionTest.java
@@ -8,29 +8,35 @@
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.junit.Assert.assertEquals;
 
+import com.android.tools.r8.NeverInline;
 import com.android.tools.r8.TestParameters;
-import com.android.tools.r8.TestParametersCollection;
-import com.android.tools.r8.ToolHelper;
-import com.android.tools.r8.utils.AndroidApiLevel;
+import com.android.tools.r8.utils.BooleanUtils;
 import com.android.tools.r8.utils.StringUtils;
 import com.android.tools.r8.utils.codeinspector.ClassSubject;
 import com.android.tools.r8.utils.codeinspector.CodeInspector;
+import java.util.List;
 import java.util.function.Function;
+import org.junit.Assume;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
 
 @RunWith(Parameterized.class)
 public class JavaUtilFunctionTest extends CoreLibDesugarTestBase {
 
   private final TestParameters parameters;
+  private final boolean shrinkCoreLibrary;
+  private static final String expectedOutput = StringUtils.lines("Hello, world", "Hello, world");
 
-  @Parameterized.Parameters(name = "{0}")
-  public static TestParametersCollection data() {
-    return getTestParameters().withDexRuntimes().withAllApiLevels().build();
+  @Parameters(name = "{1}, shrinkCoreLibrary: {0}")
+  public static List<Object[]> data() {
+    return buildParameters(
+        BooleanUtils.values(), getTestParameters().withDexRuntimes().withAllApiLevels().build());
   }
 
-  public JavaUtilFunctionTest(TestParameters parameters) {
+  public JavaUtilFunctionTest(boolean shrinkDesugaredLibrary, TestParameters parameters) {
+    this.shrinkCoreLibrary = shrinkDesugaredLibrary;
     this.parameters = parameters;
   }
 
@@ -53,22 +59,42 @@
   }
 
   @Test
-  public void testJavaUtilFunction() throws Exception {
-    String expectedOutput = StringUtils.lines("Hello, world", "Hello, world");
+  public void testJavaUtilFunctionD8() throws Exception {
     testForD8()
         .addInnerClasses(JavaUtilFunctionTest.class)
-        .addLibraryFiles(ToolHelper.getAndroidJar(AndroidApiLevel.P))
         .setMinApi(parameters.getApiLevel())
-        .enableCoreLibraryDesugaring()
+        .enableCoreLibraryDesugaring(parameters.getApiLevel())
         .compile()
         .inspect(this::checkRewrittenArguments)
-        .addRunClasspathFiles(buildDesugaredLibrary(parameters.getApiLevel()))
+        .addDesugaredCoreLibraryRunClassPath(
+            this::buildDesugaredLibrary, parameters.getApiLevel(), shrinkCoreLibrary)
+        .run(parameters.getRuntime(), TestClass.class)
+        .assertSuccessWithOutput(expectedOutput);
+  }
+
+  @Test
+  public void testJavaUtilFunctionR8() throws Exception {
+    // TODO(b/139398549): Enable test on API 26+.
+    Assume.assumeTrue(parameters.getApiLevel().getLevel() < 26);
+    testForR8(parameters.getBackend())
+        // Following two for checkRewrittenArguments.
+        .enableInliningAnnotations()
+        .noMinification()
+        .addKeepMainRule(TestClass.class)
+        .addInnerClasses(JavaUtilFunctionTest.class)
+        .setMinApi(parameters.getApiLevel())
+        .enableCoreLibraryDesugaring(parameters.getApiLevel())
+        .compile()
+        .inspect(this::checkRewrittenArguments)
+        .addDesugaredCoreLibraryRunClassPath(
+            this::buildDesugaredLibrary, parameters.getApiLevel(), shrinkCoreLibrary)
         .run(parameters.getRuntime(), TestClass.class)
         .assertSuccessWithOutput(expectedOutput);
   }
 
   static class TestClass {
 
+    @NeverInline
     private static String applyFunction(Function<String, String> f) {
       return f.apply("Hello, world");
     }
diff --git a/src/test/java/com/android/tools/r8/desugar/corelib/ProgramRewritingTest.java b/src/test/java/com/android/tools/r8/desugar/corelib/ProgramRewritingTest.java
index 8aeddab..0d18a6f 100644
--- a/src/test/java/com/android/tools/r8/desugar/corelib/ProgramRewritingTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/corelib/ProgramRewritingTest.java
@@ -13,14 +13,15 @@
 import static org.hamcrest.core.StringContains.containsString;
 import static org.junit.Assert.assertFalse;
 
+import com.android.tools.r8.D8TestCompileResult;
 import com.android.tools.r8.D8TestRunResult;
+import com.android.tools.r8.R8TestCompileResult;
 import com.android.tools.r8.R8TestRunResult;
 import com.android.tools.r8.TestParameters;
 import com.android.tools.r8.ToolHelper;
 import com.android.tools.r8.ToolHelper.DexVm;
 import com.android.tools.r8.utils.AndroidApiLevel;
 import com.android.tools.r8.utils.BooleanUtils;
-import com.android.tools.r8.utils.Box;
 import com.android.tools.r8.utils.StringUtils;
 import com.android.tools.r8.utils.codeinspector.ClassSubject;
 import com.android.tools.r8.utils.codeinspector.CodeInspector;
@@ -56,26 +57,25 @@
   @Test
   public void testProgramD8() throws Exception {
     Assume.assumeTrue("No desugaring for high API levels", requiresCoreLibDesugaring(parameters));
-    Box<String> keepRulesHolder = new Box<>("");
-    D8TestRunResult d8TestRunResult =
+    D8TestCompileResult d8TestCompileResult =
         testForD8()
             .addProgramFiles(Paths.get(ToolHelper.EXAMPLES_JAVA9_BUILD_DIR + "stream.jar"))
             .addLibraryFiles(ToolHelper.getAndroidJar(AndroidApiLevel.P))
             .setMinApi(parameters.getApiLevel())
-            .addOptionsModification(
-                options ->
-                    options.testing.desugaredLibraryKeepRuleConsumer =
-                        (string, handler) -> keepRulesHolder.set(keepRulesHolder.get() + string))
             .enableCoreLibraryDesugaring()
             .compile()
-            .inspect(this::checkRewrittenInvokes)
+            .inspect(this::checkRewrittenInvokes);
+    D8TestRunResult d8TestRunResult =
+        d8TestCompileResult
             .addRunClasspathFiles(
                 buildDesugaredLibrary(
-                    parameters.getApiLevel(), keepRulesHolder.get(), shrinkCoreLibrary))
+                    parameters.getApiLevel(),
+                    d8TestCompileResult.getDesugaredLibraryKeepRules(),
+                    shrinkCoreLibrary))
             .run(parameters.getRuntime(), TEST_CLASS)
             .assertSuccess();
     assertLines2By2Correct(d8TestRunResult.getStdOut());
-    assertGeneratedKeepRulesAreCorrect(keepRulesHolder.get());
+    assertGeneratedKeepRulesAreCorrect(d8TestCompileResult.getDesugaredLibraryKeepRules());
     String stdErr = d8TestRunResult.getStdErr();
     if (parameters.getRuntime().asDex().getVm().isOlderThanOrEqual(DexVm.ART_4_4_4_HOST)) {
       // Flaky: There might be a missing method on lambda deserialization.
@@ -91,28 +91,27 @@
   public void testProgramR8() throws Exception {
     Assume.assumeTrue("No desugaring for high API levels", requiresCoreLibDesugaring(parameters));
     for (Boolean minifying : BooleanUtils.values()) {
-      Box<String> keepRulesHolder = new Box<>("");
-      R8TestRunResult r8TestRunResult =
+      R8TestCompileResult r8TestCompileResult =
           testForR8(parameters.getBackend())
               .minification(minifying)
               .addKeepMainRule(TEST_CLASS)
               .addProgramFiles(Paths.get(ToolHelper.EXAMPLES_JAVA9_BUILD_DIR + "stream.jar"))
               .addLibraryFiles(ToolHelper.getAndroidJar(AndroidApiLevel.P))
               .setMinApi(parameters.getApiLevel())
-              .addOptionsModification(
-                  options ->
-                      options.testing.desugaredLibraryKeepRuleConsumer =
-                          (string, handler) -> keepRulesHolder.set(keepRulesHolder.get() + string))
               .enableCoreLibraryDesugaring()
-              .compile()
+              .compile();
+      R8TestRunResult r8TestRunResult =
+          r8TestCompileResult
               .inspect(this::checkRewrittenInvokes)
               .addRunClasspathFiles(
                   buildDesugaredLibrary(
-                      parameters.getApiLevel(), keepRulesHolder.get(), shrinkCoreLibrary))
+                      parameters.getApiLevel(),
+                      r8TestCompileResult.getDesugaredLibraryKeepRules(),
+                      shrinkCoreLibrary))
               .run(parameters.getRuntime(), TEST_CLASS)
               .assertSuccess();
       assertLines2By2Correct(r8TestRunResult.getStdOut());
-      assertGeneratedKeepRulesAreCorrect(keepRulesHolder.get());
+      assertGeneratedKeepRulesAreCorrect(r8TestCompileResult.getDesugaredLibraryKeepRules());
       if (parameters.getRuntime().asDex().getVm().isOlderThanOrEqual(DexVm.ART_4_4_4_HOST)) {
         // Flaky: There might be a missing method on lambda deserialization.
         r8TestRunResult.assertStderrMatches(