Print a warning if a Proguard configuration rule does not match anything

Bug: 128494963, 135940168
Change-Id: I01a899e638e29bde339cc9c52277a9ab0b436211
diff --git a/src/main/java/com/android/tools/r8/R8.java b/src/main/java/com/android/tools/r8/R8.java
index a8afcfc..0c3a045 100644
--- a/src/main/java/com/android/tools/r8/R8.java
+++ b/src/main/java/com/android/tools/r8/R8.java
@@ -346,6 +346,8 @@
         assert appView.rootSet().verifyKeptMethodsAreTargetedAndLive(appViewWithLiveness.appInfo());
         assert appView.rootSet().verifyKeptTypesAreLive(appViewWithLiveness.appInfo());
 
+        appView.rootSet().checkAllRulesAreUsed(options);
+
         if (options.proguardSeedsConsumer != null) {
           ByteArrayOutputStream bytes = new ByteArrayOutputStream();
           PrintStream out = new PrintStream(bytes);
diff --git a/src/main/java/com/android/tools/r8/shaking/ProguardConfigurationRule.java b/src/main/java/com/android/tools/r8/shaking/ProguardConfigurationRule.java
index 3af5cba..90f4afc 100644
--- a/src/main/java/com/android/tools/r8/shaking/ProguardConfigurationRule.java
+++ b/src/main/java/com/android/tools/r8/shaking/ProguardConfigurationRule.java
@@ -12,6 +12,9 @@
 import java.util.stream.StreamSupport;
 
 public abstract class ProguardConfigurationRule extends ProguardClassSpecification {
+
+  private boolean used = false;
+
   ProguardConfigurationRule(
       Origin origin,
       Position position,
@@ -31,6 +34,14 @@
         inheritanceIsExtends, memberRules);
   }
 
+  public boolean isUsed() {
+    return used;
+  }
+
+  public void markAsUsed() {
+    used = true;
+  }
+
   abstract String typeString();
 
   String modifierString() {
diff --git a/src/main/java/com/android/tools/r8/shaking/RootSetBuilder.java b/src/main/java/com/android/tools/r8/shaking/RootSetBuilder.java
index bef1b15..562f39d 100644
--- a/src/main/java/com/android/tools/r8/shaking/RootSetBuilder.java
+++ b/src/main/java/com/android/tools/r8/shaking/RootSetBuilder.java
@@ -533,6 +533,7 @@
 
     private void materializeIfRule(ProguardIfRule rule, Set<DexReference> preconditions) {
       ProguardIfRule materializedRule = rule.materialize(preconditions);
+      rule.markAsUsed();
 
       // We need to abort class inlining of classes that could be matched by the condition of this
       // -if rule.
@@ -1051,6 +1052,7 @@
           dependentKeepClassCompatRule
               .computeIfAbsent(precondition.asDexClass().getType(), i -> new HashSet<>())
               .add(keepRule);
+          context.markAsUsed();
         }
       }
       if (!modifiers.allowsShrinking) {
@@ -1062,26 +1064,35 @@
         } else {
           noShrinking.computeIfAbsent(item.toReference(), i -> new HashSet<>()).add(keepRule);
         }
+        context.markAsUsed();
       }
       if (!modifiers.allowsOptimization) {
         noOptimization.add(item.toReference());
+        context.markAsUsed();
       }
       if (!modifiers.allowsObfuscation) {
         noObfuscation.add(item.toReference());
+        context.markAsUsed();
       }
       if (modifiers.includeDescriptorClasses) {
         includeDescriptorClasses(item, keepRule);
+        context.markAsUsed();
       }
     } else if (context instanceof ProguardAssumeMayHaveSideEffectsRule) {
       mayHaveSideEffects.put(item.toReference(), rule);
+      context.markAsUsed();
     } else if (context instanceof ProguardAssumeNoSideEffectRule) {
       noSideEffects.put(item.toReference(), rule);
+      context.markAsUsed();
     } else if (context instanceof ProguardWhyAreYouKeepingRule) {
       reasonAsked.computeIfAbsent(item.toReference(), i -> i);
+      context.markAsUsed();
     } else if (context instanceof ProguardAssumeValuesRule) {
       assumedValues.put(item.toReference(), rule);
+      context.markAsUsed();
     } else if (context instanceof ProguardCheckDiscardRule) {
       checkDiscarded.computeIfAbsent(item.toReference(), i -> i);
+      context.markAsUsed();
     } else if (context instanceof InlineRule) {
       if (item.isDexEncodedMethod()) {
         switch (((InlineRule) context).getType()) {
@@ -1097,6 +1108,7 @@
           default:
             throw new Unreachable();
         }
+        context.markAsUsed();
       }
     } else if (context instanceof ClassInlineRule) {
       switch (((ClassInlineRule) context).getType()) {
@@ -1108,6 +1120,7 @@
         default:
           throw new Unreachable();
       }
+      context.markAsUsed();
     } else if (context instanceof ClassMergingRule) {
       switch (((ClassMergingRule) context).getType()) {
         case NEVER:
@@ -1118,6 +1131,7 @@
         default:
           throw new Unreachable();
       }
+      context.markAsUsed();
     } else if (context instanceof MemberValuePropagationRule) {
       switch (((MemberValuePropagationRule) context).getType()) {
         case NEVER:
@@ -1127,11 +1141,13 @@
             DexEncodedField field = item.asDexEncodedField();
             if (field.isProgramField(appView)) {
               neverPropagateValue.add(item.asDexEncodedField().field);
+              context.markAsUsed();
             }
           } else if (item.isDexEncodedMethod()) {
             DexEncodedMethod method = item.asDexEncodedMethod();
             if (method.isProgramMethod(appView)) {
               neverPropagateValue.add(item.asDexEncodedMethod().method);
+              context.markAsUsed();
             }
           }
           break;
@@ -1141,17 +1157,23 @@
     } else if (context instanceof ProguardIdentifierNameStringRule) {
       if (item.isDexEncodedField()) {
         identifierNameStrings.add(item.asDexEncodedField().field);
+        context.markAsUsed();
       } else if (item.isDexEncodedMethod()) {
         identifierNameStrings.add(item.asDexEncodedMethod().method);
+        context.markAsUsed();
       }
     } else if (context instanceof ConstantArgumentRule) {
       if (item.isDexEncodedMethod()) {
         keepParametersWithConstantValue.add(item.asDexEncodedMethod().method);
+        context.markAsUsed();
       }
     } else if (context instanceof UnusedArgumentRule) {
       if (item.isDexEncodedMethod()) {
         keepUnusedArguments.add(item.asDexEncodedMethod().method);
+        context.markAsUsed();
       }
+    } else {
+      throw new Unreachable();
     }
   }
 
@@ -1254,8 +1276,22 @@
       this.ifRules = Collections.unmodifiableSet(previous.ifRules);
     }
 
-    public RootSet rewrittenWithLense(GraphLense lense) {
-      return new RootSet(this, lense);
+    public void checkAllRulesAreUsed(InternalOptions options) {
+      List<ProguardConfigurationRule> rules = options.getProguardConfiguration().getRules();
+      if (rules != null) {
+        for (ProguardConfigurationRule rule : rules) {
+          if (!rule.isUsed()) {
+            String message =
+                "Proguard configuration rule does not match anything: `" + rule.toString() + "`";
+            StringDiagnostic diagnostic = new StringDiagnostic(message, rule.getOrigin());
+            if (options.testing.allowUnusedProguardConfigurationRules) {
+              options.reporter.info(diagnostic);
+            } else {
+              throw options.reporter.fatalError(diagnostic);
+            }
+          }
+        }
+      }
     }
 
     private static <T extends DexReference, S> Map<T, Map<T, S>> rewriteDependentReferenceKeys(
diff --git a/src/main/java/com/android/tools/r8/utils/InternalOptions.java b/src/main/java/com/android/tools/r8/utils/InternalOptions.java
index 7b4fcad..ae7f0e7 100644
--- a/src/main/java/com/android/tools/r8/utils/InternalOptions.java
+++ b/src/main/java/com/android/tools/r8/utils/InternalOptions.java
@@ -873,6 +873,7 @@
 
     public boolean allowTypeErrors =
         !Version.isDev() || System.getProperty("com.android.tools.r8.allowTypeErrors") != null;
+    public boolean allowUnusedProguardConfigurationRules = true;
     public boolean alwaysUsePessimisticRegisterAllocation = false;
     public boolean enableDeadSwitchCaseElimination = false;
     public boolean enableSwitchToIfRewriting = true;
diff --git a/src/test/examples/getmembers/keep-rules.txt b/src/test/examples/getmembers/keep-rules.txt
index 68c4a5d..9319c68 100644
--- a/src/test/examples/getmembers/keep-rules.txt
+++ b/src/test/examples/getmembers/keep-rules.txt
@@ -11,10 +11,6 @@
   <methods>;
 }
 
--alwaysinline class getmembers.B {
-  private String toBeInlined();
-}
-
 # This will be added to CompatProguard by default.
 # We are testing whether R8 shows the same behavior.
 -identifiernamestring public class java.lang.Class {
diff --git a/src/test/examples/mockito_interface/keep-rules-conditional-on-mock.txt b/src/test/examples/mockito_interface/keep-rules-conditional-on-mock.txt
index 67f437f..edb4c08 100644
--- a/src/test/examples/mockito_interface/keep-rules-conditional-on-mock.txt
+++ b/src/test/examples/mockito_interface/keep-rules-conditional-on-mock.txt
@@ -8,8 +8,6 @@
   public static void main(...);
 }
 
--keep class org.junit.** { *; }
--keep class org.mockito.** { *; }
 -keep @**.RunWith class * { *; }
 
 # Mockito generates mocks of interface types at runtime. If interface methods are optimized, i.e.,
diff --git a/src/test/examples/mockito_interface/keep-rules.txt b/src/test/examples/mockito_interface/keep-rules.txt
index 40dd170..b398a9b 100644
--- a/src/test/examples/mockito_interface/keep-rules.txt
+++ b/src/test/examples/mockito_interface/keep-rules.txt
@@ -8,6 +8,4 @@
   public static void main(...);
 }
 
--keep class org.junit.** { *; }
--keep class org.mockito.** { *; }
 -keep @**.RunWith class * { *; }
\ No newline at end of file
diff --git a/src/test/java/com/android/tools/r8/R8TestBuilder.java b/src/test/java/com/android/tools/r8/R8TestBuilder.java
index 4bfdded..d6d3f5d 100644
--- a/src/test/java/com/android/tools/r8/R8TestBuilder.java
+++ b/src/test/java/com/android/tools/r8/R8TestBuilder.java
@@ -185,12 +185,24 @@
     if (!enableInliningAnnotations) {
       enableInliningAnnotations = true;
       addInternalKeepRules(
-          "-forceinline class * { @" + annotationPackageName + ".ForceInline *; }",
           "-neverinline class * { @" + annotationPackageName + ".NeverInline *; }");
     }
     return self();
   }
 
+  public T enableForceInliningAnnotations() {
+    return enableForceInliningAnnotations(ForceInline.class.getPackage().getName());
+  }
+
+  public T enableForceInliningAnnotations(String annotationPackageName) {
+    if (!enableInliningAnnotations) {
+      enableInliningAnnotations = true;
+      addInternalKeepRules(
+          "-forceinline class * { @" + annotationPackageName + ".ForceInline *; }");
+    }
+    return self();
+  }
+
   public T enableClassInliningAnnotations() {
     if (!enableClassInliningAnnotations) {
       enableClassInliningAnnotations = true;
diff --git a/src/test/java/com/android/tools/r8/TestBase.java b/src/test/java/com/android/tools/r8/TestBase.java
index 16ebddf..9ec2044 100644
--- a/src/test/java/com/android/tools/r8/TestBase.java
+++ b/src/test/java/com/android/tools/r8/TestBase.java
@@ -750,14 +750,6 @@
         + keepMainProguardConfiguration(clazz);
   }
 
-  public static String keepMainProguardConfigurationWithInliningAnnotation(String clazz) {
-    return "-forceinline class * { @com.android.tools.r8.ForceInline *; }"
-        + System.lineSeparator()
-        + "-neverinline class * { @com.android.tools.r8.NeverInline *; }"
-        + System.lineSeparator()
-        + keepMainProguardConfiguration(clazz);
-  }
-
   public static String neverMergeRule() {
     return "-nevermerge @com.android.tools.r8.NeverMerge class *";
   }
diff --git a/src/test/java/com/android/tools/r8/TestCompileResult.java b/src/test/java/com/android/tools/r8/TestCompileResult.java
index d7056bb..2368eca 100644
--- a/src/test/java/com/android/tools/r8/TestCompileResult.java
+++ b/src/test/java/com/android/tools/r8/TestCompileResult.java
@@ -163,6 +163,11 @@
     return file;
   }
 
+  public CR writeToZip(Consumer<Path> fn) throws IOException {
+    fn.accept(writeToZip());
+    return self();
+  }
+
   public CR writeToZip(Path file) throws IOException {
     app.writeToZip(file, getOutputMode());
     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 1160985..a6b48a0 100644
--- a/src/test/java/com/android/tools/r8/TestCompilerBuilder.java
+++ b/src/test/java/com/android/tools/r8/TestCompilerBuilder.java
@@ -28,10 +28,7 @@
     extends TestBaseBuilder<C, B, CR, RR, T> {
 
   public static final Consumer<InternalOptions> DEFAULT_OPTIONS =
-      new Consumer<InternalOptions>() {
-        @Override
-        public void accept(InternalOptions options) {}
-      };
+      options -> options.testing.allowUnusedProguardConfigurationRules = false;
 
   final Backend backend;
 
diff --git a/src/test/java/com/android/tools/r8/accessrelaxation/ConstructorRelaxationTest.java b/src/test/java/com/android/tools/r8/accessrelaxation/ConstructorRelaxationTest.java
index 4772b91..58dfa85 100644
--- a/src/test/java/com/android/tools/r8/accessrelaxation/ConstructorRelaxationTest.java
+++ b/src/test/java/com/android/tools/r8/accessrelaxation/ConstructorRelaxationTest.java
@@ -193,11 +193,6 @@
                 "-keep class " + mainClass.getCanonicalName() + "{",
                 "  public static void main(java.lang.String[]);",
                 "}",
-                "",
-                "-keep class *.L* {",
-                "  <init>(...);",
-                "}",
-                "",
                 "-allowaccessmodification")
             .setMinApi(parameters.getRuntime())
             .run(parameters.getRuntime(), mainClass);
diff --git a/src/test/java/com/android/tools/r8/accessrelaxation/NoRelaxationForSerializableTest.java b/src/test/java/com/android/tools/r8/accessrelaxation/NoRelaxationForSerializableTest.java
index ca4d1c4..294ee96 100644
--- a/src/test/java/com/android/tools/r8/accessrelaxation/NoRelaxationForSerializableTest.java
+++ b/src/test/java/com/android/tools/r8/accessrelaxation/NoRelaxationForSerializableTest.java
@@ -135,7 +135,6 @@
   public void testR8_withKeepRules() throws Exception {
     R8TestCompileResult result = testForR8(parameters.getBackend())
         .addProgramClasses(CLASSES)
-        .enableClassInliningAnnotations()
         .enableInliningAnnotations()
         .addKeepRuleFiles(configuration)
         .addKeepRules(KEEPMEMBER_RULES)
@@ -165,7 +164,6 @@
   public void testR8_withoutKeepRules() throws Exception {
     R8TestCompileResult result = testForR8(parameters.getBackend())
         .addProgramClasses(CLASSES)
-        .enableClassInliningAnnotations()
         .enableInliningAnnotations()
         .addKeepRuleFiles(configuration)
         .setMinApi(parameters.getRuntime())
diff --git a/src/test/java/com/android/tools/r8/cf/KeepDeserializeLambdaMethodTestRunner.java b/src/test/java/com/android/tools/r8/cf/KeepDeserializeLambdaMethodTestRunner.java
index fd3245f..9c5d05d 100644
--- a/src/test/java/com/android/tools/r8/cf/KeepDeserializeLambdaMethodTestRunner.java
+++ b/src/test/java/com/android/tools/r8/cf/KeepDeserializeLambdaMethodTestRunner.java
@@ -6,6 +6,7 @@
 
 import static org.hamcrest.core.StringContains.containsString;
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assume.assumeTrue;
 
 import com.android.tools.r8.CompilationFailedException;
 import com.android.tools.r8.R8CompatTestBuilder;
@@ -48,6 +49,9 @@
 
   @Test
   public void testKeepRuleCf() throws Exception {
+    // Only run for CF runtimes, since the keep rule does not match anything when compiling for the
+    // DEX.
+    assumeTrue(parameters.isCfRuntime());
     test(true);
   }
 
diff --git a/src/test/java/com/android/tools/r8/internal/proto/Proto2ShrinkingTest.java b/src/test/java/com/android/tools/r8/internal/proto/Proto2ShrinkingTest.java
index b016e34..f5c2f27 100644
--- a/src/test/java/com/android/tools/r8/internal/proto/Proto2ShrinkingTest.java
+++ b/src/test/java/com/android/tools/r8/internal/proto/Proto2ShrinkingTest.java
@@ -51,6 +51,9 @@
               options.enableGeneratedMessageLiteShrinking = true;
               options.enableGeneratedExtensionRegistryShrinking = true;
               options.enableStringSwitchConversion = true;
+
+              // Because there are unused rules in lite_proguard.pgcfg.
+              options.testing.allowUnusedProguardConfigurationRules = true;
             })
         .minification(enableMinification)
         .setMinApi(parameters.getRuntime())
diff --git a/src/test/java/com/android/tools/r8/internal/proto/Proto3ShrinkingTest.java b/src/test/java/com/android/tools/r8/internal/proto/Proto3ShrinkingTest.java
index 31e6cff..38bdf2b 100644
--- a/src/test/java/com/android/tools/r8/internal/proto/Proto3ShrinkingTest.java
+++ b/src/test/java/com/android/tools/r8/internal/proto/Proto3ShrinkingTest.java
@@ -51,6 +51,9 @@
               options.enableGeneratedMessageLiteShrinking = true;
               options.enableGeneratedExtensionRegistryShrinking = true;
               options.enableStringSwitchConversion = true;
+
+              // Because there are unused rules in lite_proguard.pgcfg.
+              options.testing.allowUnusedProguardConfigurationRules = true;
             })
         .minification(enableMinification)
         .setMinApi(parameters.getRuntime())
diff --git a/src/test/java/com/android/tools/r8/ir/analysis/type/MissingClassesJoinTest.java b/src/test/java/com/android/tools/r8/ir/analysis/type/MissingClassesJoinTest.java
index 4d01f36..901a577 100644
--- a/src/test/java/com/android/tools/r8/ir/analysis/type/MissingClassesJoinTest.java
+++ b/src/test/java/com/android/tools/r8/ir/analysis/type/MissingClassesJoinTest.java
@@ -70,7 +70,6 @@
               .addProgramClasses(A.class, ASub1.class, Box.class, TestClass.class)
               .addKeepAllClassesRule()
               .addOptionsModification(options -> options.testing.allowTypeErrors = allowTypeErrors)
-              .enableInliningAnnotations()
               .enableMergeAnnotations()
               .setMinApi(parameters.getRuntime())
               .compile()
diff --git a/src/test/java/com/android/tools/r8/ir/optimize/NonNullParamTest.java b/src/test/java/com/android/tools/r8/ir/optimize/NonNullParamTest.java
index 0c66575..07106f3 100644
--- a/src/test/java/com/android/tools/r8/ir/optimize/NonNullParamTest.java
+++ b/src/test/java/com/android/tools/r8/ir/optimize/NonNullParamTest.java
@@ -4,12 +4,16 @@
 package com.android.tools.r8.ir.optimize;
 
 import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
+import static org.hamcrest.MatcherAssert.assertThat;
 import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertThat;
 
 import com.android.tools.r8.NeverInline;
+import com.android.tools.r8.R8FullTestBuilder;
+import com.android.tools.r8.R8TestBuilder;
 import com.android.tools.r8.TestBase;
-import com.android.tools.r8.ToolHelper;
+import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.TestParametersCollection;
+import com.android.tools.r8.ThrowableConsumer;
 import com.android.tools.r8.ir.optimize.nonnull.IntrinsicsDeputy;
 import com.android.tools.r8.ir.optimize.nonnull.NonNullParamAfterInvokeDirect;
 import com.android.tools.r8.ir.optimize.nonnull.NonNullParamAfterInvokeInterface;
@@ -28,7 +32,6 @@
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.Streams;
 import java.util.Collection;
-import java.util.function.Consumer;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.junit.runners.Parameterized;
@@ -36,15 +39,15 @@
 @RunWith(Parameterized.class)
 public class NonNullParamTest extends TestBase {
 
-  private Backend backend;
+  private final TestParameters parameters;
 
-  @Parameterized.Parameters(name = "Backend: {0}")
-  public static Backend[] data() {
-    return ToolHelper.getBackends();
+  @Parameterized.Parameters(name = "{0}")
+  public static TestParametersCollection data() {
+    return getTestParameters().withAllRuntimes().build();
   }
 
-  public NonNullParamTest(Backend backend) {
-    this.backend = backend;
+  public NonNullParamTest(TestParameters parameters) {
+    this.parameters = parameters;
   }
 
   private void disableDevirtualization(InternalOptions options) {
@@ -54,19 +57,14 @@
   CodeInspector buildAndRun(
       Class<?> mainClass,
       Collection<Class<?>> classes,
-      Consumer<InternalOptions> optionsModification)
+      ThrowableConsumer<R8FullTestBuilder> configuration)
       throws Exception {
     String javaOutput = runOnJava(mainClass);
 
-    return testForR8(backend)
+    return testForR8(parameters.getBackend())
         .addProgramClasses(classes)
-        .enableProguardTestOptions()
-        .enableInliningAnnotations()
-        .enableClassInliningAnnotations()
-        .enableMergeAnnotations()
         .addKeepMainRule(mainClass)
-        .addKeepRules(
-            ImmutableList.of("-keepattributes InnerClasses,Signature,EnclosingMethod"))
+        .addKeepRules(ImmutableList.of("-keepattributes InnerClasses,Signature,EnclosingMethod"))
         // All tests are checking if invocations to certain null-check utils are gone.
         .noMinification()
         .addOptionsModification(
@@ -74,8 +72,9 @@
               // Need to increase a little bit to inline System.out.println
               options.inliningInstructionLimit = 4;
             })
-        .addOptionsModification(optionsModification)
-        .run(mainClass)
+        .apply(configuration)
+        .setMinApi(parameters.getRuntime())
+        .run(parameters.getRuntime(), mainClass)
         .assertSuccessWithOutput(javaOutput)
         .inspector();
   }
@@ -84,7 +83,10 @@
   public void testIntrinsics() throws Exception {
     Class<?> mainClass = IntrinsicsDeputy.class;
     CodeInspector inspector =
-        buildAndRun(mainClass, ImmutableList.of(NeverInline.class, mainClass), null);
+        buildAndRun(
+            mainClass,
+            ImmutableList.of(NeverInline.class, mainClass),
+            R8TestBuilder::enableInliningAnnotations);
 
     ClassSubject mainSubject = inspector.clazz(mainClass);
     assertThat(mainSubject, isPresent());
@@ -120,7 +122,7 @@
             mainClass,
             ImmutableList.of(
                 NeverInline.class, IntrinsicsDeputy.class, NotPinnedClass.class, mainClass),
-            null);
+            R8TestBuilder::enableInliningAnnotations);
 
     ClassSubject mainSubject = inspector.clazz(mainClass);
     assertThat(mainSubject, isPresent());
@@ -149,7 +151,7 @@
             mainClass,
             ImmutableList.of(
                 NeverInline.class, IntrinsicsDeputy.class, NotPinnedClass.class, mainClass),
-            null);
+            R8TestBuilder::enableInliningAnnotations);
 
     ClassSubject mainSubject = inspector.clazz(mainClass);
     assertThat(mainSubject, isPresent());
@@ -182,7 +184,7 @@
                 NonNullParamAfterInvokeVirtual.class,
                 NotPinnedClass.class,
                 mainClass),
-            null);
+            R8TestBuilder::enableInliningAnnotations);
 
     ClassSubject mainSubject = inspector.clazz(NonNullParamAfterInvokeVirtual.class);
     assertThat(mainSubject, isPresent());
@@ -217,7 +219,12 @@
                 NonNullParamAfterInvokeInterface.class,
                 NotPinnedClass.class,
                 mainClass),
-            this::disableDevirtualization);
+            builder ->
+                builder
+                    .addOptionsModification(this::disableDevirtualization)
+                    .enableInliningAnnotations()
+                    .enableClassInliningAnnotations()
+                    .enableMergeAnnotations());
 
     ClassSubject mainSubject = inspector.clazz(NonNullParamAfterInvokeInterface.class);
     assertThat(mainSubject, isPresent());
@@ -226,7 +233,7 @@
     assertThat(checkViaCall, isPresent());
     assertEquals(0, countActCall(checkViaCall));
     // The DEX backend reuses the System.out.println invoke.
-    assertEquals(backend == Backend.CF ? 2 : 1, countPrintCall(checkViaCall));
+    assertEquals(parameters.isCfRuntime() ? 2 : 1, countPrintCall(checkViaCall));
   }
 
   private long countCallToParamNullCheck(MethodSubject method) {
@@ -244,5 +251,4 @@
   private long countThrow(MethodSubject method) {
     return Streams.stream(method.iterateInstructions(InstructionSubject::isThrow)).count();
   }
-
 }
diff --git a/src/test/java/com/android/tools/r8/ir/optimize/canonicalization/DexItemBasedConstStringCanonicalizationTest.java b/src/test/java/com/android/tools/r8/ir/optimize/canonicalization/DexItemBasedConstStringCanonicalizationTest.java
index 1b8d9a2..895ff45 100644
--- a/src/test/java/com/android/tools/r8/ir/optimize/canonicalization/DexItemBasedConstStringCanonicalizationTest.java
+++ b/src/test/java/com/android/tools/r8/ir/optimize/canonicalization/DexItemBasedConstStringCanonicalizationTest.java
@@ -113,7 +113,6 @@
         testForR8(parameters.getBackend())
             .addProgramClasses(MAIN, CanonicalizationTestClass.class)
             .addKeepMainRule(MAIN)
-            .addKeepRules("-keep class **.TestClass")
             .minification(enableMinification)
             .setMinApi(parameters.getRuntime())
             .addOptionsModification(this::configure)
diff --git a/src/test/java/com/android/tools/r8/ir/optimize/checkcast/CheckCastDebugTestRunner.java b/src/test/java/com/android/tools/r8/ir/optimize/checkcast/CheckCastDebugTestRunner.java
index 52a1f72..dc86e78 100644
--- a/src/test/java/com/android/tools/r8/ir/optimize/checkcast/CheckCastDebugTestRunner.java
+++ b/src/test/java/com/android/tools/r8/ir/optimize/checkcast/CheckCastDebugTestRunner.java
@@ -4,21 +4,15 @@
 package com.android.tools.r8.ir.optimize.checkcast;
 
 import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
+import static org.hamcrest.MatcherAssert.assertThat;
 import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertThat;
 
-import com.android.tools.r8.ClassFileConsumer;
-import com.android.tools.r8.CompilationMode;
-import com.android.tools.r8.DexIndexedConsumer;
-import com.android.tools.r8.NeverInline;
-import com.android.tools.r8.R8Command;
-import com.android.tools.r8.ToolHelper;
+import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.TestParametersCollection;
 import com.android.tools.r8.debug.CfDebugTestConfig;
 import com.android.tools.r8.debug.DebugTestBase;
 import com.android.tools.r8.debug.DebugTestConfig;
 import com.android.tools.r8.debug.DexDebugTestConfig;
-import com.android.tools.r8.origin.Origin;
-import com.android.tools.r8.utils.AndroidApp;
 import com.android.tools.r8.utils.codeinspector.ClassSubject;
 import com.android.tools.r8.utils.codeinspector.CodeInspector;
 import com.android.tools.r8.utils.codeinspector.InstructionSubject;
@@ -33,47 +27,48 @@
 
 @RunWith(Parameterized.class)
 public class CheckCastDebugTestRunner extends DebugTestBase {
+
   private static final Class<?> MAIN = CheckCastDebugTest.class;
-  private final Backend backend;
+
+  private final TestParameters parameters;
 
   private Path r8Out;
   private CodeInspector inspector;
 
-  @Parameterized.Parameters(name = "Backend: {0}")
-  public static Backend[] data() {
-    return ToolHelper.getBackends();
+  @Parameterized.Parameters(name = "{0}")
+  public static TestParametersCollection data() {
+    return getTestParameters().withAllRuntimes().build();
   }
 
-  public CheckCastDebugTestRunner(Backend backend) {
-    this.backend = backend;
+  public CheckCastDebugTestRunner(TestParameters parameters) {
+    this.parameters = parameters;
   }
 
-  private static int testCounter = 0;
-
   @Before
   public void setUp() throws Exception {
-    AndroidApp app = readClasses(NeverInline.class, A.class, B.class, C.class, MAIN);
-    r8Out = temp.newFile(String.format("r8Out-%s-%d.zip", backend, testCounter++)).toPath();
-    R8Command.Builder builder = ToolHelper.prepareR8CommandBuilder(app);
-    if (backend == Backend.DEX) {
-      builder.setProgramConsumer(new DexIndexedConsumer.ArchiveConsumer(r8Out));
-    } else {
-      assert backend == Backend.CF;
-      builder.setProgramConsumer(new ClassFileConsumer.ArchiveConsumer(r8Out));
-    }
-    builder.addProguardConfiguration(
-        ImmutableList.of(
-            "-dontobfuscate",
-            keepMainProguardConfigurationWithInliningAnnotation(MAIN)),
-        Origin.unknown());
-    builder.setMode(CompilationMode.DEBUG);
-    ToolHelper.allowTestProguardOptions(builder);
-    ToolHelper.runR8(builder.build(), o -> o.enableVerticalClassMerging = false);
-    inspector = new CodeInspector(r8Out);
+    inspector =
+        testForR8(parameters.getBackend())
+            .addProgramClassesAndInnerClasses(A.class, B.class, C.class, MAIN)
+            .addKeepMainRule(MAIN)
+            .addOptionsModification(options -> options.enableVerticalClassMerging = false)
+            .debug()
+            .enableInliningAnnotations()
+            .noMinification()
+            .setMinApi(parameters.getRuntime())
+            .compile()
+            .writeToZip(this::setR8Out)
+            .run(parameters.getRuntime(), MAIN)
+            .assertSuccess()
+            .inspector();
+
     ClassSubject classSubject = inspector.clazz(MAIN);
     assertThat(classSubject, isPresent());
   }
 
+  private void setR8Out(Path path) {
+    this.r8Out = path;
+  }
+
   @Test
   public void test_differentLocals() throws Throwable {
     ClassSubject classSubject = inspector.clazz(MAIN);
@@ -83,9 +78,8 @@
         Streams.stream(method.iterateInstructions(InstructionSubject::isCheckCast)).count();
     assertEquals(0, count);
 
-    DebugTestConfig config = backend == Backend.CF
-        ? new CfDebugTestConfig()
-        : new DexDebugTestConfig();
+    DebugTestConfig config =
+        parameters.isCfRuntime() ? new CfDebugTestConfig() : new DexDebugTestConfig();
     config.addPaths(r8Out);
     runDebugTest(config, MAIN.getCanonicalName(),
         // Object obj = new C();
@@ -136,9 +130,8 @@
         Streams.stream(method.iterateInstructions(InstructionSubject::isCheckCast)).count();
     assertEquals(0, count);
 
-    DebugTestConfig config = backend == Backend.CF
-        ? new CfDebugTestConfig()
-        : new DexDebugTestConfig();
+    DebugTestConfig config =
+        parameters.isCfRuntime() ? new CfDebugTestConfig() : new DexDebugTestConfig();
     config.addPaths(r8Out);
     runDebugTest(config, MAIN.getCanonicalName(),
         // Object obj = new C();
diff --git a/src/test/java/com/android/tools/r8/ir/optimize/inliner/InliningAfterClassInitializationTest.java b/src/test/java/com/android/tools/r8/ir/optimize/inliner/InliningAfterClassInitializationTest.java
index 1144491..7b0a595 100644
--- a/src/test/java/com/android/tools/r8/ir/optimize/inliner/InliningAfterClassInitializationTest.java
+++ b/src/test/java/com/android/tools/r8/ir/optimize/inliner/InliningAfterClassInitializationTest.java
@@ -6,8 +6,8 @@
 
 import static com.android.tools.r8.utils.codeinspector.CodeMatchers.invokesMethod;
 import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
+import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.core.IsNot.not;
-import static org.junit.Assert.assertThat;
 
 import com.android.tools.r8.KeepConstantArguments;
 import com.android.tools.r8.NeverInline;
@@ -185,7 +185,6 @@
         .addKeepMainRule(mainClass)
         .enableConstantArgumentAnnotations()
         .enableInliningAnnotations()
-        .enableMergeAnnotations()
         .run(mainClass)
         .assertSuccessWithOutput(expectedOutput)
         .inspector();
diff --git a/src/test/java/com/android/tools/r8/ir/optimize/reflection/GetNameTest.java b/src/test/java/com/android/tools/r8/ir/optimize/reflection/GetNameTest.java
index 2095584..50b19d2 100644
--- a/src/test/java/com/android/tools/r8/ir/optimize/reflection/GetNameTest.java
+++ b/src/test/java/com/android/tools/r8/ir/optimize/reflection/GetNameTest.java
@@ -267,7 +267,6 @@
     R8TestRunResult result =
         testForR8(parameters.getBackend())
             .addProgramFiles(classPaths)
-            .enableInliningAnnotations()
             .addKeepMainRule(MAIN)
             .addKeepRules("-keep class **.GetName0*")
             .addKeepRules("-keepattributes InnerClasses,EnclosingMethod")
@@ -286,7 +285,6 @@
     R8TestRunResult result =
         testForR8(parameters.getBackend())
             .addProgramFiles(classPaths)
-            .enableInliningAnnotations()
             .addKeepMainRule(MAIN)
             .addKeepRules("-keep,allowobfuscation class **.GetName0*")
             .addKeepRules("-keepattributes InnerClasses,EnclosingMethod")
diff --git a/src/test/java/com/android/tools/r8/ir/optimize/string/NestedStringBuilderTest.java b/src/test/java/com/android/tools/r8/ir/optimize/string/NestedStringBuilderTest.java
index 4d05918..4c4951d 100644
--- a/src/test/java/com/android/tools/r8/ir/optimize/string/NestedStringBuilderTest.java
+++ b/src/test/java/com/android/tools/r8/ir/optimize/string/NestedStringBuilderTest.java
@@ -66,7 +66,7 @@
     R8TestCompileResult result =
         testForR8(parameters.getBackend())
             .addProgramClasses(MAIN)
-            .enableInliningAnnotations()
+            .enableForceInliningAnnotations()
             .addKeepMainRule(MAIN)
             .setMinApi(parameters.getRuntime())
             .compile();
diff --git a/src/test/java/com/android/tools/r8/ir/optimize/uninstantiatedtypes/SynchronizedMethodTest.java b/src/test/java/com/android/tools/r8/ir/optimize/uninstantiatedtypes/SynchronizedMethodTest.java
index f082098..88459a5 100644
--- a/src/test/java/com/android/tools/r8/ir/optimize/uninstantiatedtypes/SynchronizedMethodTest.java
+++ b/src/test/java/com/android/tools/r8/ir/optimize/uninstantiatedtypes/SynchronizedMethodTest.java
@@ -29,7 +29,6 @@
             .addInnerClasses(SynchronizedMethodTest.class)
             .addKeepMainRule(TestClass.class)
             .enableInliningAnnotations()
-            .enableMergeAnnotations()
             .run(TestClass.class)
             .assertSuccessWithOutput(expectedOutput)
             .inspector();
diff --git a/src/test/java/com/android/tools/r8/ir/optimize/unusedarguments/UnusedArgumentsObjectTest.java b/src/test/java/com/android/tools/r8/ir/optimize/unusedarguments/UnusedArgumentsObjectTest.java
index aabb083..17287a4 100644
--- a/src/test/java/com/android/tools/r8/ir/optimize/unusedarguments/UnusedArgumentsObjectTest.java
+++ b/src/test/java/com/android/tools/r8/ir/optimize/unusedarguments/UnusedArgumentsObjectTest.java
@@ -8,6 +8,7 @@
 
 import com.android.tools.r8.NeverClassInline;
 import com.android.tools.r8.NeverInline;
+import com.android.tools.r8.R8FullTestBuilder;
 import com.android.tools.r8.utils.codeinspector.ClassSubject;
 import com.google.common.collect.ImmutableList;
 import java.util.Collection;
@@ -108,6 +109,11 @@
   }
 
   @Override
+  public void configure(R8FullTestBuilder builder) {
+    builder.enableClassInliningAnnotations().enableInliningAnnotations();
+  }
+
+  @Override
   public Class<?> getTestClass() {
     return TestClass.class;
   }
diff --git a/src/test/java/com/android/tools/r8/ir/optimize/unusedarguments/UnusedArgumentsTestBase.java b/src/test/java/com/android/tools/r8/ir/optimize/unusedarguments/UnusedArgumentsTestBase.java
index 6c72d10..946cc63 100644
--- a/src/test/java/com/android/tools/r8/ir/optimize/unusedarguments/UnusedArgumentsTestBase.java
+++ b/src/test/java/com/android/tools/r8/ir/optimize/unusedarguments/UnusedArgumentsTestBase.java
@@ -7,6 +7,7 @@
 import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
 import static org.hamcrest.MatcherAssert.assertThat;
 
+import com.android.tools.r8.R8FullTestBuilder;
 import com.android.tools.r8.TestBase;
 import com.android.tools.r8.utils.codeinspector.ClassSubject;
 import com.android.tools.r8.utils.codeinspector.CodeInspector;
@@ -28,6 +29,10 @@
     return ImmutableList.of(new Object[] {true}, new Object[] {false});
   }
 
+  public void configure(R8FullTestBuilder builder) {
+    builder.enableInliningAnnotations();
+  }
+
   public abstract Class<?> getTestClass();
 
   public Collection<Class<?>> getAdditionalClasses() {
@@ -56,9 +61,8 @@
         .addProgramClasses(getAdditionalClasses())
         .addKeepMainRule(getTestClass())
         .minification(minification)
-        .enableInliningAnnotations()
-        .enableClassInliningAnnotations()
         .addOptionsModification(options -> options.enableSideEffectAnalysis = false)
+        .apply(this::configure)
         .compile()
         .run(getTestClass())
         .inspect(this::inspect)
diff --git a/src/test/java/com/android/tools/r8/kotlin/MetadataStripTest.java b/src/test/java/com/android/tools/r8/kotlin/MetadataStripTest.java
index 0ef7e35..204901f 100644
--- a/src/test/java/com/android/tools/r8/kotlin/MetadataStripTest.java
+++ b/src/test/java/com/android/tools/r8/kotlin/MetadataStripTest.java
@@ -52,7 +52,6 @@
             .addProgramFiles(getKotlinJarFile(folder))
             .addProgramFiles(getJavaJarFile(folder))
             .addProgramFiles(ToolHelper.getKotlinReflectJar())
-            .enableInliningAnnotations()
             .addKeepMainRule(mainClassName)
             .addKeepRules(KEEP_ANNOTATIONS)
             .addKeepRules("-keep class kotlin.Metadata")
diff --git a/src/test/java/com/android/tools/r8/maindexlist/warnings/MainDexWarningsTest.java b/src/test/java/com/android/tools/r8/maindexlist/warnings/MainDexWarningsTest.java
index e6ca563..3778392 100644
--- a/src/test/java/com/android/tools/r8/maindexlist/warnings/MainDexWarningsTest.java
+++ b/src/test/java/com/android/tools/r8/maindexlist/warnings/MainDexWarningsTest.java
@@ -6,7 +6,7 @@
 
 import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
 import static org.hamcrest.CoreMatchers.containsString;
-import static org.junit.Assert.assertThat;
+import static org.hamcrest.MatcherAssert.assertThat;
 
 import com.android.tools.r8.ForceInline;
 import com.android.tools.r8.TestBase;
@@ -31,7 +31,6 @@
   public void testNoWarningFromMainDexRules() throws Exception {
     testForR8(Backend.DEX)
         .setMinApi(AndroidApiLevel.K)
-        .enableInliningAnnotations()
         .addProgramClasses(testClasses)
         .addKeepMainRule(mainClass)
         // Include main dex rule for class Static.
@@ -45,7 +44,6 @@
   public void testWarningFromManualMainDexList() throws Exception {
     testForR8(Backend.DEX)
         .setMinApi(AndroidApiLevel.K)
-        .enableInliningAnnotations()
         .addProgramClasses(testClasses)
         .addKeepMainRule(mainClass)
         // Include explicit main dex entry for class Static.
@@ -62,7 +60,6 @@
   public void testWarningFromManualMainDexListWithRuleAsWell() throws Exception {
     testForR8(Backend.DEX)
         .setMinApi(AndroidApiLevel.K)
-        .enableInliningAnnotations()
         .addProgramClasses(testClasses)
         .addKeepMainRule(mainClass)
         // Include explicit main dex entry for class Static.
diff --git a/src/test/java/com/android/tools/r8/naming/CovariantReturnTypeTest.java b/src/test/java/com/android/tools/r8/naming/CovariantReturnTypeTest.java
index 740c906..1303232 100644
--- a/src/test/java/com/android/tools/r8/naming/CovariantReturnTypeTest.java
+++ b/src/test/java/com/android/tools/r8/naming/CovariantReturnTypeTest.java
@@ -6,8 +6,8 @@
 
 import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
 import static com.android.tools.r8.utils.codeinspector.Matchers.isRenamed;
+import static org.hamcrest.MatcherAssert.assertThat;
 import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertThat;
 
 import com.android.tools.r8.TestBase;
 import com.android.tools.r8.jasmin.JasminBuilder;
@@ -62,7 +62,7 @@
             .addProgramFiles(inputJar)
             .addKeepMainRule("package.TestClass")
             .addKeepRules("-keepconstantarguments class * { *; }")
-            .enableConstantArgumentAnnotations()
+            .enableProguardTestOptions()
             .noTreeShaking()
             .compile()
             .inspector();
diff --git a/src/test/java/com/android/tools/r8/naming/FieldNamingObfuscationDictionaryTest.java b/src/test/java/com/android/tools/r8/naming/FieldNamingObfuscationDictionaryTest.java
index 697c8b2..d028564 100644
--- a/src/test/java/com/android/tools/r8/naming/FieldNamingObfuscationDictionaryTest.java
+++ b/src/test/java/com/android/tools/r8/naming/FieldNamingObfuscationDictionaryTest.java
@@ -92,7 +92,6 @@
 
     testForR8(parameters.getBackend())
         .addInnerClasses(FieldNamingObfuscationDictionaryTest.class)
-        .enableInliningAnnotations()
         .addKeepRules("-overloadaggressively", "-obfuscationdictionary " + dictionary.toString())
         .addKeepMainRule(Runner.class)
         .setMinApi(parameters.getRuntime())
diff --git a/src/test/java/com/android/tools/r8/naming/MethodNameMinificationPrivateNamedLastTest.java b/src/test/java/com/android/tools/r8/naming/MethodNameMinificationPrivateNamedLastTest.java
index 5ff5f4b..301fe07 100644
--- a/src/test/java/com/android/tools/r8/naming/MethodNameMinificationPrivateNamedLastTest.java
+++ b/src/test/java/com/android/tools/r8/naming/MethodNameMinificationPrivateNamedLastTest.java
@@ -128,7 +128,6 @@
         .addInnerClasses(MethodNameMinificationPrivateNamedLastTest.class)
         .enableMergeAnnotations()
         .enableInliningAnnotations()
-        .enableClassInliningAnnotations()
         .addKeepMainRule(Runner.class)
         .setMinApi(parameters.getRuntime())
         .compile()
diff --git a/src/test/java/com/android/tools/r8/naming/OverloadedReservedFieldNamingTest.java b/src/test/java/com/android/tools/r8/naming/OverloadedReservedFieldNamingTest.java
index 2d0ea1c..18bc136 100644
--- a/src/test/java/com/android/tools/r8/naming/OverloadedReservedFieldNamingTest.java
+++ b/src/test/java/com/android/tools/r8/naming/OverloadedReservedFieldNamingTest.java
@@ -47,7 +47,6 @@
         .addKeepRules(
             "-keep class " + A.class.getTypeName() + " { boolean a; }",
             overloadAggressively ? "-overloadaggressively" : "")
-        .enableMergeAnnotations()
         .setMinApi(parameters.getRuntime())
         .compile()
         .inspect(this::verifyAggressiveOverloading)
diff --git a/src/test/java/com/android/tools/r8/naming/ReservedFieldNameInSuperClassTest.java b/src/test/java/com/android/tools/r8/naming/ReservedFieldNameInSuperClassTest.java
index af533e3..c687947 100644
--- a/src/test/java/com/android/tools/r8/naming/ReservedFieldNameInSuperClassTest.java
+++ b/src/test/java/com/android/tools/r8/naming/ReservedFieldNameInSuperClassTest.java
@@ -45,7 +45,6 @@
     CodeInspector inspector =
         testForR8(Backend.DEX)
             .addProgramClasses(A.class, ASub1.class, ASub2.class, TestClass.class)
-            .enableClassInliningAnnotations()
             .addKeepMainRule(TestClass.class)
             .addKeepRules(
                 reserveName
@@ -78,7 +77,6 @@
         .addProgramClasses(ASub1.class, ASub2.class, TestClass.class)
         .addLibraryClasses(A.class)
         .addLibraryFiles(runtimeJar(Backend.DEX))
-        .enableClassInliningAnnotations()
         .addKeepMainRule(TestClass.class)
         .compile()
         .addRunClasspathFiles(testForD8().addProgramClasses(A.class).compile().writeToZip())
diff --git a/src/test/java/com/android/tools/r8/naming/ReservedFieldNameInSuperInterfaceTest.java b/src/test/java/com/android/tools/r8/naming/ReservedFieldNameInSuperInterfaceTest.java
index c349aed..f7551b7 100644
--- a/src/test/java/com/android/tools/r8/naming/ReservedFieldNameInSuperInterfaceTest.java
+++ b/src/test/java/com/android/tools/r8/naming/ReservedFieldNameInSuperInterfaceTest.java
@@ -78,8 +78,6 @@
         .addProgramClasses(TestClass.class, A.class, J.class)
         .addLibraryClasses(I.class)
         .addLibraryFiles(runtimeJar(Backend.DEX))
-        .enableMemberValuePropagationAnnotations()
-        .enableMergeAnnotations()
         .addKeepMainRule(TestClass.class)
         .compile()
         .addRunClasspathFiles(testForD8().addProgramClasses(I.class).compile().writeToZip())
diff --git a/src/test/java/com/android/tools/r8/naming/applymapping/ApplyMappingAfterHorizontalMergingFieldTest.java b/src/test/java/com/android/tools/r8/naming/applymapping/ApplyMappingAfterHorizontalMergingFieldTest.java
index 61d05ef..8503e9b 100644
--- a/src/test/java/com/android/tools/r8/naming/applymapping/ApplyMappingAfterHorizontalMergingFieldTest.java
+++ b/src/test/java/com/android/tools/r8/naming/applymapping/ApplyMappingAfterHorizontalMergingFieldTest.java
@@ -90,7 +90,6 @@
   @Test
   public void b121042934() throws Exception {
     R8TestCompileResult libraryResult = testForR8(backend)
-        .enableInliningAnnotations()
         .addProgramClasses(LIBRARY_CLASSES)
         .addKeepMainRule(LibraryMain.class)
         .compile();
diff --git a/src/test/java/com/android/tools/r8/naming/b128656974/B128656974.java b/src/test/java/com/android/tools/r8/naming/b128656974/B128656974.java
index 9a0696b..234d00c 100644
--- a/src/test/java/com/android/tools/r8/naming/b128656974/B128656974.java
+++ b/src/test/java/com/android/tools/r8/naming/b128656974/B128656974.java
@@ -5,8 +5,8 @@
 
 import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
 import static com.android.tools.r8.utils.codeinspector.Matchers.isRenamed;
+import static org.hamcrest.MatcherAssert.assertThat;
 import static org.junit.Assert.assertNotEquals;
-import static org.junit.Assert.assertThat;
 
 import com.android.tools.r8.NeverClassInline;
 import com.android.tools.r8.NeverInline;
@@ -28,7 +28,6 @@
         .addProgramClasses(
             Greeting.class, Greeting.getGreetingBase(), TestClassSub.class, main)
         .enableClassInliningAnnotations()
-        .enableInliningAnnotations()
         .enableMergeAnnotations()
         .addKeepMainRule(main)
         .addKeepRules(
diff --git a/src/test/java/com/android/tools/r8/naming/retrace/DesugarLambdaRetraceTest.java b/src/test/java/com/android/tools/r8/naming/retrace/DesugarLambdaRetraceTest.java
index 143e65e..ae64e7f 100644
--- a/src/test/java/com/android/tools/r8/naming/retrace/DesugarLambdaRetraceTest.java
+++ b/src/test/java/com/android/tools/r8/naming/retrace/DesugarLambdaRetraceTest.java
@@ -6,8 +6,8 @@
 
 import static com.android.tools.r8.naming.retrace.StackTrace.isSameExceptForFileName;
 import static com.android.tools.r8.naming.retrace.StackTrace.isSameExceptForFileNameAndLineNumber;
+import static org.hamcrest.MatcherAssert.assertThat;
 import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertThat;
 
 import com.android.tools.r8.CompilationMode;
 import com.android.tools.r8.ToolHelper;
diff --git a/src/test/java/com/android/tools/r8/naming/retrace/DesugarStaticInterfaceMethodsRetraceTest.java b/src/test/java/com/android/tools/r8/naming/retrace/DesugarStaticInterfaceMethodsRetraceTest.java
index 93201b1..1574c20 100644
--- a/src/test/java/com/android/tools/r8/naming/retrace/DesugarStaticInterfaceMethodsRetraceTest.java
+++ b/src/test/java/com/android/tools/r8/naming/retrace/DesugarStaticInterfaceMethodsRetraceTest.java
@@ -5,7 +5,7 @@
 package com.android.tools.r8.naming.retrace;
 
 import static com.android.tools.r8.naming.retrace.StackTrace.isSameExceptForFileName;
-import static org.junit.Assert.assertThat;
+import static org.hamcrest.MatcherAssert.assertThat;
 
 import com.android.tools.r8.CompilationMode;
 import com.android.tools.r8.NeverInline;
diff --git a/src/test/java/com/android/tools/r8/naming/retrace/InliningRetraceTest.java b/src/test/java/com/android/tools/r8/naming/retrace/InliningRetraceTest.java
index 3f85e95..3394d60 100644
--- a/src/test/java/com/android/tools/r8/naming/retrace/InliningRetraceTest.java
+++ b/src/test/java/com/android/tools/r8/naming/retrace/InliningRetraceTest.java
@@ -6,8 +6,8 @@
 
 import static com.android.tools.r8.naming.retrace.StackTrace.isSameExceptForFileName;
 import static com.android.tools.r8.naming.retrace.StackTrace.isSameExceptForFileNameAndLineNumber;
+import static org.hamcrest.MatcherAssert.assertThat;
 import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertThat;
 
 import com.android.tools.r8.CompilationMode;
 import com.android.tools.r8.ForceInline;
diff --git a/src/test/java/com/android/tools/r8/naming/retrace/LineDeltaTest.java b/src/test/java/com/android/tools/r8/naming/retrace/LineDeltaTest.java
index 4e64e7e..2583b6e 100644
--- a/src/test/java/com/android/tools/r8/naming/retrace/LineDeltaTest.java
+++ b/src/test/java/com/android/tools/r8/naming/retrace/LineDeltaTest.java
@@ -14,21 +14,21 @@
 public class LineDeltaTest extends TestBase {
   public String runTest(Backend backend) throws Exception {
     return testForR8(backend)
-        .enableInliningAnnotations()
+        .enableForceInliningAnnotations()
         .addProgramClasses(LineDeltaTestClass.class)
         .addKeepMainRule(LineDeltaTestClass.class)
         .addKeepRules("-keepattributes LineNumberTable")
         .run(LineDeltaTestClass.class)
-        .assertSuccessWithOutput(StringUtils.lines(
-            "In test1() - 1",
-            "In test1() - 2",
-            "In test1() - 3",
-            "In test1() - 4",
-            "In test2() - 1",
-            "In test2() - 2",
-            "In test2() - 3",
-            "In test2() - 4"
-        ))
+        .assertSuccessWithOutput(
+            StringUtils.lines(
+                "In test1() - 1",
+                "In test1() - 2",
+                "In test1() - 3",
+                "In test1() - 4",
+                "In test2() - 1",
+                "In test2() - 2",
+                "In test2() - 3",
+                "In test2() - 4"))
         .proguardMap();
   }
 
diff --git a/src/test/java/com/android/tools/r8/naming/retrace/RetraceTestBase.java b/src/test/java/com/android/tools/r8/naming/retrace/RetraceTestBase.java
index 0ea1d7c..c30a265 100644
--- a/src/test/java/com/android/tools/r8/naming/retrace/RetraceTestBase.java
+++ b/src/test/java/com/android/tools/r8/naming/retrace/RetraceTestBase.java
@@ -5,6 +5,7 @@
 package com.android.tools.r8.naming.retrace;
 
 import com.android.tools.r8.CompilationMode;
+import com.android.tools.r8.R8FullTestBuilder;
 import com.android.tools.r8.R8TestRunResult;
 import com.android.tools.r8.TestBase;
 import com.google.common.collect.ImmutableList;
@@ -24,6 +25,8 @@
 
   public StackTrace expectedStackTrace;
 
+  public void configure(R8FullTestBuilder builder) {}
+
   public Collection<Class<?>> getClasses() {
     return ImmutableList.of(getMainClass());
   }
@@ -48,11 +51,10 @@
         testForR8(backend)
             .setMode(mode)
             .enableProguardTestOptions()
-            .enableMergeAnnotations()
-            .enableInliningAnnotations()
             .addProgramClasses(getClasses())
             .addKeepMainRule(getMainClass())
             .addKeepRules(keepRules)
+            .apply(this::configure)
             .run(getMainClass())
             .assertFailure();
 
diff --git a/src/test/java/com/android/tools/r8/naming/retrace/VerticalClassMergingRetraceTest.java b/src/test/java/com/android/tools/r8/naming/retrace/VerticalClassMergingRetraceTest.java
index a188b06..728f328 100644
--- a/src/test/java/com/android/tools/r8/naming/retrace/VerticalClassMergingRetraceTest.java
+++ b/src/test/java/com/android/tools/r8/naming/retrace/VerticalClassMergingRetraceTest.java
@@ -5,11 +5,12 @@
 
 import static com.android.tools.r8.naming.retrace.StackTrace.isSameExceptForFileName;
 import static com.android.tools.r8.naming.retrace.StackTrace.isSameExceptForFileNameAndLineNumber;
+import static org.hamcrest.MatcherAssert.assertThat;
 import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertThat;
 
 import com.android.tools.r8.CompilationMode;
 import com.android.tools.r8.NeverInline;
+import com.android.tools.r8.R8FullTestBuilder;
 import com.android.tools.r8.ToolHelper;
 import com.android.tools.r8.naming.retrace.StackTrace.StackTraceLine;
 import com.google.common.collect.ImmutableList;
@@ -35,6 +36,11 @@
   }
 
   @Override
+  public void configure(R8FullTestBuilder builder) {
+    builder.enableInliningAnnotations();
+  }
+
+  @Override
   public Collection<Class<?>> getClasses() {
     return ImmutableList.of(getMainClass(), ResourceWrapper.class, TintResources.class);
   }
diff --git a/src/test/java/com/android/tools/r8/proguard/configuration/UnusedKeepRuleTest.java b/src/test/java/com/android/tools/r8/proguard/configuration/UnusedKeepRuleTest.java
index ddc20f2..c28eb36 100644
--- a/src/test/java/com/android/tools/r8/proguard/configuration/UnusedKeepRuleTest.java
+++ b/src/test/java/com/android/tools/r8/proguard/configuration/UnusedKeepRuleTest.java
@@ -4,7 +4,13 @@
 
 package com.android.tools.r8.proguard.configuration;
 
+import static org.hamcrest.CoreMatchers.containsString;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.Assert.assertEquals;
+
+import com.android.tools.r8.Diagnostic;
 import com.android.tools.r8.TestBase;
+import java.util.List;
 import org.junit.Test;
 
 public class UnusedKeepRuleTest extends TestBase {
@@ -13,8 +19,19 @@
   public void test() throws Exception {
     testForR8(Backend.DEX)
         .addKeepRules("-keep class NotPresent")
+        .addOptionsModification(
+            options -> options.testing.allowUnusedProguardConfigurationRules = true)
         .compile()
-        // TODO(b/128494963): Should print a warning that the keep rule does not match anything.
-        .assertNoMessages();
+        .inspectDiagnosticMessages(
+            messages -> {
+              messages.assertOnlyInfos();
+              List<Diagnostic> infos = messages.getInfos();
+              assertEquals(1, infos.size());
+
+              Diagnostic info = infos.get(0);
+              assertThat(
+                  info.getDiagnosticMessage(),
+                  containsString("Proguard configuration rule does not match anything"));
+            });
   }
 }
diff --git a/src/test/java/com/android/tools/r8/proguard/rules/InnerClassNameSeparatorTest.java b/src/test/java/com/android/tools/r8/proguard/rules/InnerClassNameSeparatorTest.java
index fbcb8f2..a0c7b57 100644
--- a/src/test/java/com/android/tools/r8/proguard/rules/InnerClassNameSeparatorTest.java
+++ b/src/test/java/com/android/tools/r8/proguard/rules/InnerClassNameSeparatorTest.java
@@ -36,7 +36,16 @@
 
   @Test
   public void testR8() throws Exception {
-    TestRunResult<?> result = runTest(testForR8(parameters.getBackend()));
+    TestRunResult<?> result =
+        runTest(
+            testForR8(parameters.getBackend())
+                .addOptionsModification(
+                    options -> {
+                      if (separator.equals(".")) {
+                        // R8 currently does not recognize the '.' as an inner class name separator.
+                        options.testing.allowUnusedProguardConfigurationRules = true;
+                      }
+                    }));
     if (separator.equals("$")) {
       result.assertSuccessWithOutputLines("Hello world!");
     } else {
diff --git a/src/test/java/com/android/tools/r8/regress/b69825683/Regress69825683Test.java b/src/test/java/com/android/tools/r8/regress/b69825683/Regress69825683Test.java
index 624b2e4..d0cb2bf 100644
--- a/src/test/java/com/android/tools/r8/regress/b69825683/Regress69825683Test.java
+++ b/src/test/java/com/android/tools/r8/regress/b69825683/Regress69825683Test.java
@@ -76,7 +76,6 @@
             .addProgramFiles(ToolHelper.getClassFilesForTestPackage(clazz.getPackage()))
             .addKeepMainRule(clazz)
             .enableInliningAnnotations()
-            .enableSideEffectAnnotations()
             .addKeepRules(
                 "-assumemayhavesideeffects class " + clazz.getName() + " {",
                 "  void <init>(...);",
diff --git a/src/test/java/com/android/tools/r8/shaking/InvalidTypesTest.java b/src/test/java/com/android/tools/r8/shaking/InvalidTypesTest.java
index 64dbadf..b951b4f 100644
--- a/src/test/java/com/android/tools/r8/shaking/InvalidTypesTest.java
+++ b/src/test/java/com/android/tools/r8/shaking/InvalidTypesTest.java
@@ -197,13 +197,13 @@
             .addKeepRules(
                 "-keep class TestClass { public static I g; }",
                 "-neverinline class TestClass { public static void m(); }")
+            .enableProguardTestOptions()
             .addOptionsModification(
                 options -> {
                   if (mode == Mode.INVOKE_UNVERIFIABLE_METHOD) {
                     options.testing.allowTypeErrors = true;
                   }
                 })
-            .enableInliningAnnotations()
             .setMinApi(parameters.getRuntime())
             .run(parameters.getRuntime(), mainClass.name);
     checkTestRunResult(r8Result, Compiler.R8);
diff --git a/src/test/java/com/android/tools/r8/shaking/assumevalues/SynthesizedRulesFromApiLevelTest.java b/src/test/java/com/android/tools/r8/shaking/assumevalues/SynthesizedRulesFromApiLevelTest.java
index 66e49e6..1df5d9c 100644
--- a/src/test/java/com/android/tools/r8/shaking/assumevalues/SynthesizedRulesFromApiLevelTest.java
+++ b/src/test/java/com/android/tools/r8/shaking/assumevalues/SynthesizedRulesFromApiLevelTest.java
@@ -6,14 +6,16 @@
 
 import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
 import static org.hamcrest.CoreMatchers.not;
+import static org.hamcrest.MatcherAssert.assertThat;
 import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertThat;
 import static org.junit.Assert.assertTrue;
 
 import com.android.tools.r8.D8;
 import com.android.tools.r8.D8Command;
 import com.android.tools.r8.OutputMode;
+import com.android.tools.r8.R8FullTestBuilder;
 import com.android.tools.r8.TestBase;
+import com.android.tools.r8.ThrowableConsumer;
 import com.android.tools.r8.ToolHelper;
 import com.android.tools.r8.ToolHelper.DexVm;
 import com.android.tools.r8.jasmin.JasminBuilder;
@@ -154,9 +156,11 @@
       AndroidApiLevel runtimeApiLevel,
       AndroidApiLevel nativeApiLevel,
       String expectedOutput,
+      ThrowableConsumer<R8FullTestBuilder> configuration,
       Consumer<CodeInspector> inspector,
       List<String> additionalKeepRules,
-      SynthesizedRule synthesizedRule) throws Exception{
+      SynthesizedRule synthesizedRule)
+      throws Exception {
     assertTrue(runtimeApiLevel.getLevel() >= buildApiLevel.getLevel());
     if (backend == Backend.DEX) {
       testForR8(backend)
@@ -166,6 +170,7 @@
           .addKeepRules("-neverinline class " + compatLibraryClassName + " { *; }")
           .addKeepMainRule(mainClassName)
           .addKeepRules(additionalKeepRules)
+          .apply(configuration)
           .compile()
           .inspectSyntheticProguardRules(
               syntheticProguardRules ->
@@ -180,6 +185,7 @@
           .addProgramFiles(buildApp(nativeApiLevel))
           .addKeepMainRule(mainClassName)
           .addKeepRules(additionalKeepRules)
+          .apply(configuration)
           .compile()
           .inspectSyntheticProguardRules(this::noSynthesizedRules)
           .addRunClasspathFiles(
@@ -200,6 +206,7 @@
         runtimeApiLevel,
         nativeApiLevel,
         expectedOutput,
+        null,
         inspector,
         ImmutableList.of(),
         SynthesizedRule.PRESENT);
@@ -266,24 +273,32 @@
         AndroidApiLevel.O_MR1,
         AndroidApiLevel.O_MR1,
         expectedResultForNative(AndroidApiLevel.O_MR1),
+        builder ->
+            builder.addOptionsModification(
+                options ->
+                    // android.os.Build$VERSION only exists in the Android runtime.
+                    options.testing.allowUnusedProguardConfigurationRules = backend == Backend.CF),
         this::compatCodeNotPresent,
         ImmutableList.of(
             "-assumevalues class android.os.Build$VERSION { public static final int SDK_INT return "
-            + AndroidApiLevel.O_MR1.getLevel() + "..1000; }"),
+                + AndroidApiLevel.O_MR1.getLevel()
+                + "..1000; }"),
         SynthesizedRule.NOT_PRESENT);
   }
 
   @Test
   public void testExplicitAssumeValuesRulesWhichMatchAndKeepCompat() throws Exception {
     Assume.assumeTrue(ToolHelper.getDexVm().isNewerThan(DexVm.ART_7_0_0_HOST));
-    String[] rules = new String[] {
-        "-assumevalues class * { int SDK_INT return 1..1000; }",
-        "-assumevalues class * { % SDK_INT return 1..1000; }",
-        "-assumevalues class * { int * return 1..1000; }",
-        "-assumevalues class * extends java.lang.Object { int SDK_INT return 1..1000; }",
-        "-assumevalues class * { <fields>; }",
-        "-assumevalues class * { *; }"
-    };
+    String[] rules =
+        new String[] {
+          "-assumevalues class android.os.Build$VERSION { int SDK_INT return 1..1000; }",
+          "-assumevalues class android.os.Build$VERSION { % SDK_INT return 1..1000; }",
+          "-assumevalues class android.os.Build$VERSION { int * return 1..1000; }",
+          "-assumevalues class android.os.Build$VERSION extends java.lang.Object { int SDK_INT"
+              + " return 1..1000; }",
+          "-assumevalues class android.os.Build$VERSION { <fields>; }",
+          "-assumevalues class android.os.Build$VERSION { *; }"
+        };
 
     for (String rule : rules) {
       runTest(
@@ -291,6 +306,9 @@
           AndroidApiLevel.O_MR1,
           AndroidApiLevel.O_MR1,
           expectedResultForNative(AndroidApiLevel.O_MR1),
+          builder ->
+              builder.addOptionsModification(
+                  options -> options.testing.allowUnusedProguardConfigurationRules = true),
           this::compatCodePresent,
           ImmutableList.of(rule),
           SynthesizedRule.NOT_PRESENT);
@@ -313,6 +331,9 @@
           AndroidApiLevel.O_MR1,
           AndroidApiLevel.O_MR1,
           expectedResultForNative(AndroidApiLevel.O_MR1),
+          builder ->
+              builder.addOptionsModification(
+                  options -> options.testing.allowUnusedProguardConfigurationRules = true),
           this::compatCodeNotPresent,
           ImmutableList.of(rule),
           SynthesizedRule.PRESENT);
diff --git a/src/test/java/com/android/tools/r8/shaking/attributes/EnclosingMethodTest.java b/src/test/java/com/android/tools/r8/shaking/attributes/EnclosingMethodTest.java
index 26647a4..7110c5c 100644
--- a/src/test/java/com/android/tools/r8/shaking/attributes/EnclosingMethodTest.java
+++ b/src/test/java/com/android/tools/r8/shaking/attributes/EnclosingMethodTest.java
@@ -85,7 +85,6 @@
   public void testR8() throws Exception {
     testForR8(parameters.getBackend())
         .addProgramFiles(classPaths)
-        .enableInliningAnnotations()
         .addOptionsModification(this::configure)
         .addKeepMainRule(MAIN)
         .addKeepRules("-keep class **.GetName*")
diff --git a/src/test/java/com/android/tools/r8/shaking/ifrule/interfacemethoddesugaring/IfRuleWithInterfaceMethodDesugaringTest.java b/src/test/java/com/android/tools/r8/shaking/ifrule/interfacemethoddesugaring/IfRuleWithInterfaceMethodDesugaringTest.java
index 07d6d22..e03101a 100644
--- a/src/test/java/com/android/tools/r8/shaking/ifrule/interfacemethoddesugaring/IfRuleWithInterfaceMethodDesugaringTest.java
+++ b/src/test/java/com/android/tools/r8/shaking/ifrule/interfacemethoddesugaring/IfRuleWithInterfaceMethodDesugaringTest.java
@@ -10,8 +10,8 @@
 import static com.android.tools.r8.utils.codeinspector.Matchers.isStatic;
 import static org.hamcrest.CoreMatchers.allOf;
 import static org.hamcrest.CoreMatchers.not;
+import static org.hamcrest.MatcherAssert.assertThat;
 import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertThat;
 
 import com.android.tools.r8.NeverClassInline;
 import com.android.tools.r8.NeverInline;
@@ -46,6 +46,8 @@
                 "  !public !static void virtualMethod();",
                 "}",
                 "-keep class " + Unused2.class.getTypeName())
+            .addOptionsModification(
+                options -> options.testing.allowUnusedProguardConfigurationRules = true)
             .enableInliningAnnotations()
             .enableClassInliningAnnotations()
             .enableMergeAnnotations()
diff --git a/src/test/java/com/android/tools/r8/shaking/ifrule/verticalclassmerging/ImplementsMergedTypeDirectlyTest.java b/src/test/java/com/android/tools/r8/shaking/ifrule/verticalclassmerging/ImplementsMergedTypeDirectlyTest.java
index 840295e..ec06ebc 100644
--- a/src/test/java/com/android/tools/r8/shaking/ifrule/verticalclassmerging/ImplementsMergedTypeDirectlyTest.java
+++ b/src/test/java/com/android/tools/r8/shaking/ifrule/verticalclassmerging/ImplementsMergedTypeDirectlyTest.java
@@ -9,8 +9,8 @@
 import static org.hamcrest.core.IsNot.not;
 import static org.junit.Assert.assertTrue;
 
+import com.android.tools.r8.R8FullTestBuilder;
 import com.android.tools.r8.TestParameters;
-import com.android.tools.r8.utils.InternalOptions;
 import com.android.tools.r8.utils.codeinspector.ClassSubject;
 import com.android.tools.r8.utils.codeinspector.CodeInspector;
 
@@ -29,13 +29,13 @@
   }
 
   @Override
-  public void configure(InternalOptions options) {
-    super.configure(options);
+  public void configure(R8FullTestBuilder builder) {
+    super.configure(builder);
 
     // If unused interface removal is enabled, the `implements K` clause will be removed prior to
     // vertical class merging (by the tree pruner).
     // TODO(b/135083634): Should handle unused interfaces similar to vertically merged classes.
-    options.enableUnusedInterfaceRemoval = false;
+    builder.addOptionsModification(options -> options.enableUnusedInterfaceRemoval = false);
   }
 
   @Override
diff --git a/src/test/java/com/android/tools/r8/shaking/ifrule/verticalclassmerging/ImplementsMergedTypeIndirectlyTest.java b/src/test/java/com/android/tools/r8/shaking/ifrule/verticalclassmerging/ImplementsMergedTypeIndirectlyTest.java
index 83953fc..2b76994 100644
--- a/src/test/java/com/android/tools/r8/shaking/ifrule/verticalclassmerging/ImplementsMergedTypeIndirectlyTest.java
+++ b/src/test/java/com/android/tools/r8/shaking/ifrule/verticalclassmerging/ImplementsMergedTypeIndirectlyTest.java
@@ -6,8 +6,8 @@
 
 import static org.junit.Assert.assertEquals;
 
+import com.android.tools.r8.R8FullTestBuilder;
 import com.android.tools.r8.TestParameters;
-import com.android.tools.r8.utils.InternalOptions;
 import com.android.tools.r8.utils.codeinspector.ClassSubject;
 import com.android.tools.r8.utils.codeinspector.CodeInspector;
 
@@ -26,13 +26,13 @@
   }
 
   @Override
-  public void configure(InternalOptions options) {
-    super.configure(options);
+  public void configure(R8FullTestBuilder builder) {
+    super.configure(builder);
 
     // If unused interface removal is enabled, the `implements J` clause will be removed by the tree
     // pruner.
     // TODO(b/135083634): Should handle unused interfaces similar to vertically merged classes.
-    options.enableUnusedInterfaceRemoval = false;
+    builder.addOptionsModification(options -> options.enableUnusedInterfaceRemoval = false);
   }
 
   @Override
diff --git a/src/test/java/com/android/tools/r8/shaking/ifrule/verticalclassmerging/MergedReturnTypeTest.java b/src/test/java/com/android/tools/r8/shaking/ifrule/verticalclassmerging/MergedReturnTypeTest.java
index a1fa185..47f1c08 100644
--- a/src/test/java/com/android/tools/r8/shaking/ifrule/verticalclassmerging/MergedReturnTypeTest.java
+++ b/src/test/java/com/android/tools/r8/shaking/ifrule/verticalclassmerging/MergedReturnTypeTest.java
@@ -11,6 +11,7 @@
 import static org.junit.Assert.assertNotEquals;
 
 import com.android.tools.r8.AssumeMayHaveSideEffects;
+import com.android.tools.r8.R8FullTestBuilder;
 import com.android.tools.r8.TestParameters;
 import com.android.tools.r8.utils.codeinspector.ClassSubject;
 import com.android.tools.r8.utils.codeinspector.CodeInspector;
@@ -38,6 +39,12 @@
   }
 
   @Override
+  public void configure(R8FullTestBuilder builder) {
+    super.configure(builder);
+    builder.enableSideEffectAnnotations();
+  }
+
+  @Override
   public Class<?> getTestClass() {
     return TestClass.class;
   }
@@ -83,6 +90,12 @@
     }
 
     @Override
+    public void configure(R8FullTestBuilder builder) {
+      super.configure(builder);
+      builder.enableSideEffectAnnotations();
+    }
+
+    @Override
     public Class<?> getTestClass() {
       return TestClass.class;
     }
diff --git a/src/test/java/com/android/tools/r8/shaking/ifrule/verticalclassmerging/MergedTypeBaseTest.java b/src/test/java/com/android/tools/r8/shaking/ifrule/verticalclassmerging/MergedTypeBaseTest.java
index 965fc10..c0ab377 100644
--- a/src/test/java/com/android/tools/r8/shaking/ifrule/verticalclassmerging/MergedTypeBaseTest.java
+++ b/src/test/java/com/android/tools/r8/shaking/ifrule/verticalclassmerging/MergedTypeBaseTest.java
@@ -9,10 +9,10 @@
 import static org.hamcrest.core.IsNot.not;
 import static org.junit.Assert.assertEquals;
 
+import com.android.tools.r8.R8FullTestBuilder;
 import com.android.tools.r8.TestBase;
 import com.android.tools.r8.TestParameters;
 import com.android.tools.r8.utils.BooleanUtils;
-import com.android.tools.r8.utils.InternalOptions;
 import com.android.tools.r8.utils.codeinspector.CodeInspector;
 import com.google.common.collect.ImmutableList;
 import java.util.Collection;
@@ -67,6 +67,11 @@
         getTestParameters().withAllRuntimes().build(), BooleanUtils.values());
   }
 
+  public void configure(R8FullTestBuilder builder) {
+    builder.addOptionsModification(
+        options -> options.enableVerticalClassMerging = enableVerticalClassMerging);
+  }
+
   public abstract Class<?> getTestClass();
 
   public String getAdditionalKeepRules() {
@@ -100,16 +105,10 @@
             "-keep class " + Unused.class.getTypeName(),
             getAdditionalKeepRules())
         .noMinification()
-        .addOptionsModification(this::configure)
-        .enableClassInliningAnnotations()
-        .enableSideEffectAnnotations()
         .setMinApi(parameters.getRuntime())
+        .apply(this::configure)
         .run(parameters.getRuntime(), getTestClass())
         .assertSuccessWithOutput(expected)
         .inspect(this::inspect);
   }
-
-  public void configure(InternalOptions options) {
-    options.enableVerticalClassMerging = enableVerticalClassMerging;
-  }
 }
diff --git a/src/test/java/com/android/tools/r8/shaking/keptgraph/KeptByFieldReflectionTestRunner.java b/src/test/java/com/android/tools/r8/shaking/keptgraph/KeptByFieldReflectionTestRunner.java
index a2d5ba7..0c06960 100644
--- a/src/test/java/com/android/tools/r8/shaking/keptgraph/KeptByFieldReflectionTestRunner.java
+++ b/src/test/java/com/android/tools/r8/shaking/keptgraph/KeptByFieldReflectionTestRunner.java
@@ -66,7 +66,6 @@
     GraphInspector inspector =
         testForR8(backend)
             .enableGraphInspector(consumer)
-            .enableInliningAnnotations()
             .addProgramClasses(CLASSES)
             .addKeepMainRule(CLASS)
             .run(CLASS)
diff --git a/src/test/java/com/android/tools/r8/shaking/keptgraph/KeptByMethodReflectionTestRunner.java b/src/test/java/com/android/tools/r8/shaking/keptgraph/KeptByMethodReflectionTestRunner.java
index 4f226fe..c8afcdc 100644
--- a/src/test/java/com/android/tools/r8/shaking/keptgraph/KeptByMethodReflectionTestRunner.java
+++ b/src/test/java/com/android/tools/r8/shaking/keptgraph/KeptByMethodReflectionTestRunner.java
@@ -63,7 +63,6 @@
     GraphInspector inspector =
         testForR8(backend)
             .enableGraphInspector(consumer)
-            .enableInliningAnnotations()
             .addProgramClasses(CLASSES)
             .addKeepMainRule(CLASS)
             .run(CLASS)
diff --git a/src/test/java/com/android/tools/r8/shaking/keptgraph/KeptByTwoRulesTestRunner.java b/src/test/java/com/android/tools/r8/shaking/keptgraph/KeptByTwoRulesTestRunner.java
index 975361e..5623924 100644
--- a/src/test/java/com/android/tools/r8/shaking/keptgraph/KeptByTwoRulesTestRunner.java
+++ b/src/test/java/com/android/tools/r8/shaking/keptgraph/KeptByTwoRulesTestRunner.java
@@ -53,7 +53,6 @@
     GraphInspector inspector =
         testForR8(backend)
             .enableGraphInspector()
-            .enableInliningAnnotations()
             .addProgramClasses(CLASSES)
             .addKeepRules(keepPublicRule, keepFooRule)
             .run(CLASS)
diff --git a/src/test/java/com/android/tools/r8/shaking/keptgraph/KeptViaClassInitializerTestRunner.java b/src/test/java/com/android/tools/r8/shaking/keptgraph/KeptViaClassInitializerTestRunner.java
index d211971..ddf82f0 100644
--- a/src/test/java/com/android/tools/r8/shaking/keptgraph/KeptViaClassInitializerTestRunner.java
+++ b/src/test/java/com/android/tools/r8/shaking/keptgraph/KeptViaClassInitializerTestRunner.java
@@ -91,7 +91,6 @@
     GraphInspector inspector =
         testForR8(backend)
             .enableGraphInspector(consumer)
-            .enableInliningAnnotations()
             .addProgramClassesAndInnerClasses(Main.class, A.class, T.class)
             .addKeepMethodRules(mainMethod)
             .setMinApi(AndroidApiLevel.N)
diff --git a/src/test/java/com/android/tools/r8/shaking/proxy/MockitoTest.java b/src/test/java/com/android/tools/r8/shaking/proxy/MockitoTest.java
index 1a8b97d..82234e7 100644
--- a/src/test/java/com/android/tools/r8/shaking/proxy/MockitoTest.java
+++ b/src/test/java/com/android/tools/r8/shaking/proxy/MockitoTest.java
@@ -6,7 +6,7 @@
 import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
 import static com.android.tools.r8.utils.codeinspector.Matchers.isRenamed;
 import static org.hamcrest.CoreMatchers.not;
-import static org.junit.Assert.assertThat;
+import static org.hamcrest.MatcherAssert.assertThat;
 
 import com.android.tools.r8.R8FullTestBuilder;
 import com.android.tools.r8.TestBase;
@@ -74,5 +74,4 @@
     assertThat(mtd, isPresent());
     assertThat(mtd, not(isRenamed()));
   }
-
 }
diff --git a/src/test/java/com/android/tools/r8/shaking/whyareyoukeeping/WhyAreYouKeepingTest.java b/src/test/java/com/android/tools/r8/shaking/whyareyoukeeping/WhyAreYouKeepingTest.java
index d78542e..fd948ab 100644
--- a/src/test/java/com/android/tools/r8/shaking/whyareyoukeeping/WhyAreYouKeepingTest.java
+++ b/src/test/java/com/android/tools/r8/shaking/whyareyoukeeping/WhyAreYouKeepingTest.java
@@ -137,6 +137,8 @@
         .addProgramClasses(A.class)
         .addKeepMethodRules(Reference.methodFromMethod(A.class.getMethod("foo")))
         .addKeepRules("-whyareyoukeeping class NonExistentClass")
+        .addOptionsModification(
+            options -> options.testing.allowUnusedProguardConfigurationRules = true)
         // Redirect the compilers stdout to intercept the '-whyareyoukeeping' output
         .redirectStdOut(new PrintStream(baos))
         .compile();